构建WebRTC技术需要的后端服务

news2024/11/16 3:48:43
  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创
  • 📢作者格言:新的征程,我们面对的不是技术而是人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !

在这里插入图片描述

序言

当下直播界最炙手可热的技术,WebRTC应该时其中之一,而想在此技术领域登堂入室,确实有很多的知识和积累需要熟悉和学习,作为一个技术新手,怎么从懵懂到会用再到理解内涵而会心一笑,确实是挺难的一件事情。

也许我们永远也无法企及大师的项背,但有一点可以坚信,只要我们努力去学习,会使用这个最简单而直接的要求肯定能达到。

1. WebRTC技术

WebRTC(Web实时通信)是一种开放标准和技术,用于在Web浏览器之间实现实时通信,包括音频、视频和数据传输。它是由Google推出的,并得到了其他大型技术公司的支持和采用,目前众多的浏览器都已经支持WebRTC了,因此其应用也越来越多。

WebRTC的主要特点包括:

  1. 实时通信:WebRTC允许实时的音频、视频和数据传输,使用户可以通过浏览器直接进行语音和视频通话,而无需其他插件或软件。

  2. 网页集成:WebRTC可以直接集成到Web浏览器中,通过JavaScript API进行操作,无需下载或安装额外的应用程序。

  3. 点对点通信:WebRTC支持点对点(peer-to-peer)通信,这意味着数据可以直接在两个浏览器之间传输,而无需通过中间服务器。这种直接的通信方式可以提高速度和减少延迟。

  4. 安全性:WebRTC使用安全的传输协议(如SRTP)来保护音频和视频通信的隐私和安全性。它还支持加密和身份验证,确保通信的机密性和完整性。

  5. 开放标准:WebRTC是一个开放的标准,由W3C和IETF进行标准化和规范化。这意味着它是一个公开的技术,并且可以被广泛采用和支持。

WebRTC技术的特点使其在在线会议、远程协作、客户支持和实时通信应用中得到广泛应用。它提供了一种简单、便捷和安全的方式来进行实时通信,为用户提供了更好的体验和互动性。

2. 信令服务

虽然WebRTC支持点对点通信,但它仍然需要服务器,以便客户端可以交换元数据,通过称为信令的过程协调通信,并处理网络地址转换器(NAT)和防火墙。

这里我们主要介绍如何构建信令服务,以及如何处理与 STUN 和 TURN 服务器进行实际连接的行为。当然它还解释了WebRTC应用程序如何处理多方呼叫并与VoIP和PSTN(也称为电话)等服务进行交互。

如果您不熟悉WebRTC的基础知识,请在阅读本文之前参阅WebRTC入门。

那么,什么是信令呢?

信令是协调通信的过程。

为了使WebRTC应用程序能够配置呼叫,其客户端需要交换以下信息:

  • 用于打开或关闭通信的会话控制消息
  • 错误消息
  • 多媒体元数据,例如编解码器、编解码器设置、带宽和媒体类型
  • 用于建立安全连接的关键数据
  • 网络数据,例如外界看到的主机的 IP 地址和端口

此信令过程需要和客户端来回传递消息,该机制不是由WebRTC API实现的,您需要亲自构建它。

2.1 为什么WebRTC没有定义信令?

为了避免冗余并最大限度地与现有技术兼容,WebRTC标准没有指定信令方法和协议。

JavaScript 会话建立协议 (JSEP) 概述了此方法:

WebRTC呼叫背后的思想是完全指定和控制媒体,尽可能将信令留给应用程序。理由是不同的应用程序可能更喜欢使用不同的协议,例如现有的 SIP 或 Jingle 呼叫信令协议,或者针对特定应用程序自定义的内容。

JSEP 的体系结构还避免了浏览器必须保存状态,即充当信号状态机的功能。例如,如果每次重新加载页面时都会丢失信令数据,这将是一个问题。相反,信令状态可以保存在服务器上,这样看起来架构就更完美了,下图是JSEP体系架构。

在这里插入图片描述

JSEP 要求新的的交换在提问者offer 和 回答者answer之间, 即上面提到的媒体元数据。OfferAnswer以会话描述协议 (SDP) 格式传达,如下所示:

v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2

想知道所有这些SDP胡言乱语实际上意味着什么吗?可以查看互联网工程任务组 (IETF) 示例。

请记住,WebRTC的设计使得在通过编辑SDP文本中的值设置为本地或远程描述之前可以调整offeranswer。例如,appr.tc 中的函数可用于设置默认编解码器和比特率。

SDP用JavaScript操作起来有些痛苦,并且有关于WebRTC的未来版本是否应该使用JSON的讨论,但是坚持使用SDP也有一些优点。

2.2 Alice呼叫Eve

当Alice想要呼叫Eve时,使用WebRTC的过程大致如下:

  1. Alice打开她的Web浏览器,并通过getUserMedia方法获取她的音频和视频流。这将启动她的摄像头和麦克风。

  2. Alice创建一个RTCPeerConnection对象,这是WebRTC中用于建立对等连接的主要对象。

  3. Alice将她的本地流(音频和视频)添加到RTCPeerConnection对象中。

  4. Alice创建一个数据通道(Data Channel),这是用于在对等连接之间传输任意数据的通道。数据通道可以用于发送文本消息、文件等。

  5. Alice为数据通道设置消息接收的回调函数,以便在收到来自Eve的消息时进行处理。

  6. Alice创建一个offer(邀请),其中包含她的媒体信息和网络配置。这个offer描述了Alice希望与Eve建立连接的条件。

  7. Alice将她的本地描述(offer)设置为RTCPeerConnection的本地描述。

  8. Alice通过信令服务器将她的本地描述发送给Eve。信令服务器充当中介,帮助Alice和Eve交换网络配置和媒体信息。

  9. Eve收到Alice的本地描述,并创建一个RTCPeerConnection对象。

  10. Eve将她的本地流(音频和视频)添加到RTCPeerConnection对象中。

  11. Eve将Alice的本地描述设置为她的RTCPeerConnection的远程描述。

  12. Eve创建一个answer(回答),其中包含她的媒体信息和网络配置。这个answer是对Alice的offer的回应。

  13. Eve将她的本地描述(answer)设置为RTCPeerConnection的本地描述。

  14. Eve通过信令服务器将她的本地描述发送给Alice。

  15. Alice收到Eve的本地描述,并将其设置为她的RTCPeerConnection的远程描述。

  16. Alice和Eve的RTCPeerConnection对象之间开始进行ICE(Interactive Connectivity Establishment)协商,以确定最佳的网络连接路径。

  17. 一旦ICE协商完成,Alice和Eve之间的对等连接建立成功,他们可以通过数据通道交换消息、音频和视频。

总的来说,WebRTC通过使用RTCPeerConnection对象和信令服务器来协调双方之间的通信,使Alice能够呼叫Eve并建立实时的音视频通信。

JSEP 支持 ICE Candidate Trickling,它允许呼叫者在初始报价后以增量方式向被呼叫者提供候选人,并允许被呼叫者开始对呼叫执行操作并建立连接,而无需等待所有候选人到达。

2.3 使用信令

看下代码,如下:

// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    // send the offer to the other peer
    signaling.send({desc: pc.localDescription});
  } catch (err) {
    console.error(err);
  }
};

// After remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
  // Don't set srcObject again if it is already set.
  if (remoteView.srcObject) return;
  remoteView.srcObject = event.streams[0];
};

// Call start() to initiate.
async function start() {
  try {
    // Get local stream, show it in self-view, and add it to be sent.
    const stream =
      await navigator.mediaDevices.getUserMedia(constraints);
    stream.getTracks().forEach((track) =>
      pc.addTrack(track, stream));
    selfView.srcObject = stream;
  } catch (err) {
    console.error(err);
  }
}

signaling.onmessage = async ({desc, candidate}) => {
  try {
    if (desc) {
      // If you get an offer, you need to reply with an answer.
      if (desc.type === 'offer') {
        await pc.setRemoteDescription(desc);
        const stream =
          await navigator.mediaDevices.getUserMedia(constraints);
        stream.getTracks().forEach((track) =>
          pc.addTrack(track, stream));
        await pc.setLocalDescription(await pc.createAnswer());
        signaling.send({desc: pc.localDescription});
      } else if (desc.type === 'answer') {
        await pc.setRemoteDescription(desc);
      } else {
        console.log('Unsupported SDP type.');
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

更多详细的代码,可以参看一个例子程序。

2.4 发现对方

这是一种奇特的提问方式,我如何找到可以交谈的人?

对于电话呼叫,您有电话号码和目录。对于在线视频聊天和消息传递,您需要身份和状态管理系统,以及用户启动会话的方法。WebRTC应用程序需要一种方法,让客户端相互发出信号,表明他们想要开始或加入通话。

对等发现机制不是由WebRTC定义的,该过程可以像通过电子邮件发送或消息传递 URL 一样简单。对于视频聊天应用(如对讲和浏览器会议),您可以通过共享自定义链接来邀请他人加入通话。

2.5 如何构建信令服务

重申一下,信令协议和机制不是由WebRTC标准定义的

无论您选择什么,都需要一个中间服务器在客户端之间交换信令消息和应用程序数据。可悲的是,网络应用程序不能简单地对互联网大喊:“将我连接到我的朋友!”

值得庆幸的是,信令消息很小,主要在通话开始时交换。在视频聊天会话的测试中,信令服务总共处理了大约 30-45 条消息,所有消息的总大小约为 10KB。

除了在带宽方面相对不要求外,WebRTC信令服务不会消耗太多的处理或内存,因为它们只需要中继消息并保留少量会话状态数据,例如连接了哪些客户端。

2.6 将消息从服务器推送到客户端

用于信令的消息服务必须是双向的:客户端到服务器和服务器到客户端。

双向通信违背了HTTP客户端/服务器请求/响应模型,但是多年来已经开发了各种技术黑客行为,例如长轮询,以便将数据从Web服务器上运行的服务推送到浏览器中运行的Web应用程序。

最近,EventSource API 已被广泛实现。这将启用服务器发送的事件 - 通过 HTTP 从 Web 服务器发送到浏览器客户端的数据。 专为单向消息传递而设计,但它可以与 XHR 结合使用,以构建用于交换信令消息的服务。信令服务通过向被叫方推送消息来传递来自呼叫方的消息,该消息由 XHR 请求传递。

WebSocket 是一种更自然的解决方案,专为全双工客户端-服务器通信而设计 - 可以同时在两个方向上流动的消息。使用纯 WebSocket 或服务器发送的事件, 构建的信令服务的一个优点是,这些 API 的后端可以在各种 Web 框架上实现,这些框架是大多数 Web 托管包(如 PHP、Python 和 Ruby)通用的。

当然,也可以通过让WebRTC客户端通过Ajax反复轮询消息传递服务器来处理信令,但这会导致大量冗余的网络请求,这对于移动设备来说尤其成问题。即使在建立会话后,对等方也需要轮询信令消息,以防其他对等方更改或会话终止。

2.7 现成的信令服务器

如果你不想自己动手,有几个WebRTC信令服务器可用,它们使用 Socket.IO ,并与WebRTC客户端JavaScript库集成:

  • webRTC.io 是WebRTC最早的抽象库之一。
  • Signalmaster是为与SimpleWebRTC JavaScript客户端库一起使用而创建的信令服务器。

如果你根本不想写任何代码,可以从vLine,OpenTok和Asterisk等公司获得完整的商业WebRTC平台。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言】三子棋----详解

目录 前言 一、游戏规则 二、创建文件 1.test.c文件 😄菜单函数的实现 😄main函数的实现 😄game游戏函数的实现 2.game.c文件 😄书写初始化棋盘的函数: 😄书写打印棋盘的函数 😄书写玩家…

iSCSI磁盘配置

iSCSI磁盘简要描述 iSCSI(Internet Small Computer System Interface),Internet小型计算机系统接口,又称为IP-SAN,是一种基于因特网及SCSI-3协议下的存储技术。 iSCSI 可以与任意类型的 SCSI 设备进行通信。对于一个…

【阿里巴巴1688API接口开发系列】数据采集获取,封装接口可加高并发,大数据中心项目

首先以1688商品数据为例 item_get-获得1688商品详情 公共参数 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)注册Key和secret接入secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_…

Kafka request.log中RequestQueueTimeMs、LocalTimeMs、RemoteTimeMs、ThrottleTimeMs、含义

Kafka request.log中RequestQueueTimeMs、LocalTimeMs、RemoteTimeMs、ThrottleTimeMs、含义 要理解各个延时项的含义,必须从Kafka收到TCP请求、处理请求到返回TCP包整个流程开始梳理 RequestQueueTimeMs Processor 执行processNewResponses() 方法,不…

DPWWN1靶场详解

DPWWN1靶场详解 首先还是nmap -sP 192.168.102.0/24扫描到ip地址,然后对这个ip进行一个单独的扫描,发现这个靶场有一个mysql数据库,猜测可能会用到sql注入,但是没用到。 ip登陆到网页发现并没有什么可利用的 唯一的切入点也就数…

【Docker】Docker之镜像上传(阿里云镜像仓库)

注册阿里云镜像仓库 登录阿里云 登录成功后,搜索docker镜像 点击立即开通 创建个人实例 创建镜像仓库 点击下一步之后,可以选择代码源,本文选择的是本地仓库 镜像仓库创建成功,根据对应操作命令实现想要的功能,如上传镜…

Java 动态规划 剑指 Offer 47. 礼物的最大价值

代码展示&#xff1a; class Solution {public int maxValue(int[][] grid) {int mgrid.length;int ngrid[0].length;//创建dp数组int[][]dpnew int[m1][n1];//填充数组for(int i1;i<m;i){for(int j1;j<n;j){dp[i][j]Math.max(dp[i-1][j],dp[i][j-1])grid[i-1][j-1];}}r…

LLM模型微调方法总结

文章目录 Freeze方法P-tuning方法prefix-tuningPrompt TuningP-tuning v1P-tuning v2 Lora方法Qlora方法 在现在这大规模语言模型&#xff08;LLM&#xff09;盛行的时代&#xff0c;由于模型参数和显卡配置的因素&#xff0c;预训练基本是大公司或者高校可以完成的事情&#x…

SpringBoot+Prometheus+Grafana 监控面板(项目配置方式【入侵】)

SpringBootPrometheusGrafana 监控面板 提示&#xff1a;本文使用SpringBoot 简单样例&#xff0c;介绍基础配置和使用方法 包含内容&#xff1a;Docker、SpringBoot、Maven、 Prometheus、Grafana等 提示&#xff1a;本文包含官网内容介绍&#xff0c;具体更项目的学习&#x…

怎么学习Web框架和库相关知识?

学习Web框架和库相关知识可以帮助你构建高效、可扩展和安全的Web应用程序。以下是一些学习Web框架和库的方法和步骤&#xff1a; 确定学习目标&#xff1a; 明确你想学习的Web框架或库&#xff0c;例如常用的PHP框架&#xff08;如Laravel、Symfony&#xff09;或JavaScript库…

香橙派4和树莓派4B构建K8S集群实践之八: TiDB

目录 1. 说明 2. 准备工作 3. 安装 3.1 参考TiDB官方 v1.5安装说明 3.2 准备存储类 3.3 创建crd 3.4 执行operator 3.5 创建cluster/dashboard/monitor容器组 3.6 装好后的容器状况 3.7 设置访问入口(Ingress & Port) 4. 遇到的问题 5. 参考 1. 说明 建立TiDB…

Mongo可视化工具studio 3t无限试用

文章目录 前言一、下载二、使用步骤1.下载后,无脑下一步安装好2.开始无限试用 总结 前言 mongodb可以说是比较流行的nosql数据库了,它灵活多变的存储,为项目中后续可能的变更提供了极大的便利性,工欲善其事必先利其器,今天推荐一款mongo的可视化工具: studio 3t 一、下载 各版…

Linux驱动进阶(一)——设备驱动中的并发控制

文章目录 前言并发与竞争原子变量操作原子变量操作原子整型操作原子位操作 自旋锁自旋锁概述自旋锁的使用自旋锁的使用注意事项 信号量信号量概述信号量的实现信号量的使用自旋锁与信号量的对比 完成量完成量概述完成量的实现完成量的使用 小结 前言 现代操作系统有三大特征&a…

华为云流水线CodeArts Pipeline怎么样?能实现哪些功能?

华为云流水线服务CodeArts Pipeline&#xff0c;旨在提升编排体验&#xff0c;开放插件平台&#xff0c;并提供标准化的DevOps企业治理模型&#xff0c;将华为公司内的优秀研发实践赋能给伙伴和客户。 灵活编排、高效调度 开放流水线插件 内置企业DevOps研发治理模型 体验通…

Mysql常见的集群方案

一&#xff0c;MySQL Replication MySQL Replication 是官方提供的主从同步方案&#xff0c;用于将一个 MySQL 的实例同步到另一个实例中。Replication 为保证数据安全做了重要的保证&#xff0c;是目前运用最广的 MySQL 容灾方案。Replication 用两个或以上的实例搭建了 MySQ…

driftingblues3靶机详解

driftingblues3靶机复盘 打完这个靶机后发现自己最近一段时间进步了很多&#xff0c;并且有了一些自己的思想。 这里扫除来一个22和80端口&#xff0c;大概率是要用到ssh远程登陆的。 扫描ip的同时扫描了一下目录&#xff0c;发现扫描出来很多目录&#xff0c;这里我还很窃喜&…

linux中miniconda的重装问题

linux中miniconda的重装问题Linux安装condaconda使用yaml创建虚拟环境 注意问题&#xff1a; 安装minconda时&#xff1a; 安装好之后&#xff0c;把别人的环境直接复制到自己的‘miniconda3/envs’下&#xff0c;再修改该文件的拥有者和群组 source .bashrc 重新激活 问题…

虚幻引擎程序化资源生成框架PCG 之 UPCGBlueprintElement源码笔记(一)

UPCGBlueprintElement是PCGGraph中自定义节点的基类&#xff0c;但官方目前还没有给出详细的文档&#xff0c;所以从源代码里找点答案。 文章目录 可覆盖函数&#xff08;Override Functions&#xff09;Excute 和 Excute with ContextLoop Body函数和Loop函数Point Loop Body和…

LabVIEW-通过子VI实现组合数

一、题目 已知组合数 请根据这一计算规则&#xff0c;封装设计子程序&#xff0c;实现的计算&#xff0c;并编写测试程序验证子VI设计的正确性。 二、过程 设置数值输入控件的“属性”-“数据输入”-“最小值”为1&#xff0c;当输入值为0时强制转换为1。在程序框图界面放置…

更新换代IDEA和插件啦

1.背景介绍 在2019年的时候接触到IDEA了&#xff0c;本站也先后学习了IDEA的相关知识&#xff0c;当时一直到3个月前也一直都使用的是IDEA2018.2的版本&#xff0c;常用的各种插件也都是基于这个版本应用的不亦乐乎。期间也有在自己的电脑中体验过2021的版本&#xff0c;但是办…