- +1
WebRTC的工作原理
作者:Tsahi Levent-Levi
翻译:Alex
技术审校 | 刘连响
Easy-Tech #032#
WebRTC 由很多模块构成。你想了解它的工作原理吗?
WebRTC 工作起来就像施魔法一样。你将浏览器指向一个 URL,让其他人也将他的浏览器指向一个 URL,然后,你们就能看到彼此了。是不是很酷?
如果你了解 WebRTC 内部的工作原理,你就会知道那里发生了很多事。
我将从不同角度向大家解释 WebRTC 的工作原理。最后,它们将向你呈现出 WebRTC 的完整面貌。
WebRTC 的基本概念
下面是我介绍 WebRTC 时首先强调的两点:
WebRTC 原生支持 Web 浏览器进行实时通信
WebRTC 是使用 JavaScript API 的媒体引擎
WebRTC 是一种直接在 Web 浏览器内部实现实时通信(语音、音频和任意数据)的方法,无需任何插件和下载。
从另一方面看,WebRTC 只是一个媒体引擎,其上层是 JavaScript API,每个人都知道如何使用它(尽管浏览器实现依然各不相同)。所以从这一角度,我就不多做解释了。
现在,让我们从浏览器的角度开始了解真正令 WebRTC 独一无二的原因。
如果到现在为止,当你想到 Web 应用的时候,呈现在你眼前的是客户端和服务器:
你将浏览器作为客户端,它连接服务器后,并向其请求内容(让我们称之为请求)。服务器对请求发送响应。这里我们先抛开 WebSocket,但它们的内在原理是一样的。如果我想给正在使用浏览器的朋友发送一条信息,这条信息需要先来到服务器,从那里再发送给我的朋友。这与现实生活中的邮局非常相似。
WebRTC 的交互流程和上述的流程不大一样。
虽然我们仍然需要以某种方式从一个浏览器向另一个浏览器发送信令(以便我们能够相互定位),但一旦发送信令结束,我们就可以直接在两个浏览器之间发送消息 —— 而 Web 服务器永远不会获取到这些消息。是不是像魔法一样?
这也是 WebRTC 被称为点对点技术(简称为 P2P)的原因。因为浏览器之间可以直接通信。
媒体和信令的分离
在加载网页时,我们已经习惯了浏览器为了渲染页面要去获取 100 种不同的资源,这些资源来自各种不同的服务器:页面的托管服务器、保存静态文件的 CDN 和一些第三方网站。也就是说,这些文件主要被分为三类:
HTML 和 CSS,构成了网站及其形式的主要内容
JS,通常运行网站的交互部分
图片文件和其他类似资源
最终,静态文件和少许代码的组合实现了这一切。
而 WebRTC 不同。
它需要通过网络进行两种类型的交互:信令和媒体。
信令传输发生在 HTTPS 连接或者 WebSocket 上,通过 JS 代码实现。你在信令中所做的就是决定用户找到彼此,并开启对话。关于信令有一件很重要的事:它并不是 WebRTC 的组成部分。由开发人员决定如何传递创建 WebRTC 会话所需的信息。WebRTC 将生成发送所需的信息,并处理接收到的信息,但它不会在网络上对这些信息进行任何操作。现在,WebRTC 将这些信息打包进 SDP 消息中。
实际的媒体在一个完全不同的媒介和连接上传输:“媒体渠道(media channels)”。需要使用 SRTP(用于语音和视频)或者 SCTP(用于数据通道)实现。
与信令不同,媒体选择了一条不同的路线在网络上进行传输,并且表现也大不相同。对于你需要运行的浏览器、网络和服务器,情况也是如此。
音频和视频
音频和视频是你在使用 WebRTC 需要注意的主要内容。在几乎所有的 WebRTC 示例和 demo 中,你都可以看到它们的展示。原因非常简单,视频非常直观,并且交互性强。WebRTC 中的音频和视频使用编解码器进行工作。编解码器是用于压缩和解压缩视频和音频数据的已知算法。WebRTC 中有很多不同的编解码器供你使用,这里我就不细说了。
音频和视频还有一个有趣的地方,就是它们需要低延迟发送。如果数据包因为网络出现问题而丢失,那么再重新传输它们可能就没有什么价值了(这是另外一个和 HTML 不一样的地方)。
WebRTC 使用 VoIP 技术处理媒体,并将其通过网络发送,这一切都在 SRTP(RTP 的安全、加密版本)之上进行。通过使用 SRTP 中的特定机制(以前并未广泛使用),WebRTC 做了一些小的修改,如果你已经部署了 VoIP 服务,那么它们的互操作将变得更难。
数据
你也可以使用 WebRTC 传输任意数据,这个过程在 WebRTC 中的数据通道(data channel)中完成。
当你想要在浏览器之间直接传输信息而不通过任何服务器时(你也许仍然需要一个 TURN 服务器转发消息),就可以使用数据通道。
NAT 穿越
能够直接通过浏览器通信当然很棒,但是却并不总行得通。
三四十年以前,互联网创建在客户端 - 服务器模式上,并在之后进行了适度的修改。今天,大部分用户从防火墙或者 NAT 后方访问互联网,这些设备通常会更改用户设备的 IP 地址,并将其在开放网络中屏蔽。这种屏蔽有时也会提供某种 “保护” 措施,防止未经请求的流量流向用户设备。这种方法的问题在于,WebRTC 使用了多种用于信令和媒体的媒介,所以为分辨流量是否被请求带来了困难。
此外,有些企业强调不允许任何类型的流量在未经审查的情况下进入他们的网络。这就产生了下列场景:
由于发起了 STUN 请求,左侧小人现在实际可能知道右侧小人的公有 IP 地址。但是公有 IP 地址也许只对 STUN 服务器开放,其他人想要通过创建的 “针孔(pinhole)” 进行连接依然会失败。
想要克服这些问题(用户设备无法直接与其他私有网络中的设备直接通信),解决办法是通过公有服务器转发被阻止的媒体。这就是 TURN 服务器的目的:
预计 5~20% 的会话都会使用到 TURN 服务器。
由于这种复杂性,WebRTC 会话的实现要经过以下几个步骤:
向 Web 服务器发送 SDP 请求。这条信息描述了设备想要交换的媒体通道,以及如何找到它们。
通过 Web 服务器接收到一条来自其他设备的 SDP 回复。记住,其他设备有可能是媒体服务器。
开启一个被称为 ICE(Interactive Connectivity Establishment,交互连接建立)协商的程序,目的是确定设备是否可直接访问、点对点传输或者是否需要通过 TURN 转发媒体。这个过程最好使用 trickle ICE 完成,但要以后才能实现。
一旦完成,媒体就可以在设备之间通信了。
以上这些步骤需要在浏览器上使用 JS 进行异步编程,使用 JS Promises 也能实现。在服务器端,你可以使用任何你想管理媒体和信令的工具。
很多时候,开发者不会直接针对 WebRTC API 进行开发,而会使用第三方框架和模块(开源或者商业)来做这件事。
WebRTC 工作原理速览
WebRTC 直接在浏览器间发送数据:P2P。
它可以实时发送音频、视频或者任意数据。
它需要通过 NAT 穿越机制使浏览器之间相互访问。
有时,P2P 必须经过中继服务器(TURN)。
使用 WebRTC,你需要考虑到信令和媒体,它们彼此分离。
并不一定要使用 P2P,它只是一种选择。你也可以在需要时使用媒体服务器。这种方式 “破坏” 了 P2P,但是我们的目的是解决问题,而不是写学术论文。
WebRTC 中你需要的服务器包括:
信令服务器(或者作为你的应用服务器的一部分,或者是一个独立个体)。
STUN/TURN 服务器(用于 NAT 穿越)。
媒体服务器(可选,只有在你的用例需要时才使用)
WebRTC API 观点
WebRTC 拥有三个 API,分别是:
getUserMedia
getUserMedia 负责让用户访问摄像头、麦克风和屏幕。它仅为本地执行的操作提供服务,而无法实现实时对话。下列是 getUserMedia 的一些用法:
获取用户头像图片
收集音频样本,将它们发送给音频转文本的引擎
录制音频和视频(不会因为丢包而导致质量下降)
我敢肯定你可以想到它的更多用法。
PeerConnection
PeerConnection 是 WebRCT 的核心内容,也是最难实现和理解的部分。在某种程度上,它是万能的。
它负责处理所有 SDP 信息交换(不是将它们通过网络发送,而是生成信息并处理传入的信息)。
为了连接媒体通道,它实现了 ICE(如果需要,它会经过 TURN 转发信息)。
它可以实时编码、解码视频和音频数据。
它通过网络发送和接收媒体。
它通过使用自适应 jitter buffer、带宽估计、丢包隐藏和前向纠错等算法处理网络问题(虽然你很不想了解这些算法,但最后都需要学习)。
使用回声消除等算法处理本地音频问题。
大部分这些影响最终媒体质量的操作(发生在 PeerConnection 内部)都是基于探测:一组特定规则。因此,不同的实现也许具有不同的表现和媒体质量。
DataChannel
我之前曾讨论过数据通道(data channel)。
这里我唯一要补充的是:
数据通道可以配置为可靠或者非可靠。如果将它设置为非可靠,那么信息将无法自动通过它重传。有时,这要看你的个人喜好。数据通道也可以被配置为有序和无序传输信息。
数据通道被设计为在类似于 WebSocket 的 API 上运行,一旦你打开它,你可以按照类似的方式进行操作。
你可以在这里找到更多使用数据通道的方法:
https://bloggeek.me/webrtc-data-channel-uses/
WebRTC 实现者的观点
如果你想利用 WebRTC 实现一个应用,你需要处理以下活动:
客户端
客户端可以是浏览器、移动应用、PC 应用,也可以是嵌入式设备。
对于 Web 浏览器来说,你需使用 JavaScript 进行开发:或者直接使用 WebRTC 的 API(不太可能),或者使用现存的框架,很多开发者会从 Github 开始(只要确保你选择的是最近更新的流行平台即可)。
对于移动应用来说,最重要的是找到适合你使用的 SDK。Github 上有一些可以选用,也可以使用来自 Google 的一些官方 SDK(用于 iOS 和 Android)。有些商业的 SDK 也很好用。
对于 PC 应用,你可以通过 Electron 实现。也可以使用嵌入式方法,这意味着你或者将官方的 Google WebRTC 代码库移植到你的设备上,或者自己开发。这两种方法都有效。
信令
你需要信令服务器。WebRTC 客户端做的第一件事就是连接信令服务器。这么做的目的是协调你发起的任何会话。
信令服务器并不在 WebRTC 规定的范围之内,所以你需要自行决定在此处使用的代码。大部分代码你可以在 Github 中找到,实际上浏览器客户端将会成为信令服务器的实现。
请记住信令服务器可以和你的 Web 服务器分开,或者它们位于同一进程中(由你自己来决定)。不管如何,首先要做的是检查是否已经为你的应用提供了某种信令机制,用于检查非 WebRTC 事务。你也许可以在此机制上搭载 SDP 信息和其他与信令服务器相关的 WebRTC。
NAT 穿越
NAT 穿越需要部署 STUN/TURN 服务器。我们先来看看哪些事不要做:
不要认为你不需要 TURN。
不要使用公有 STUN 服务器。
不要让一台服务器做所有事。
不要从构建世界级服务器网络开始,你会实现它,但需要时间。
现在来看看你该做哪些事:
将 STUN 和 TURN 部署在同一服务器,在相同进程。
使用 coturn(大家都在用)。
或者从他人那里获得 NAT 穿越服务,XirSys 和 Twilio 都是很好的选择。
媒体
如果你计划开启群组语音和视频会话、连接到 PSTN 或其他网络,录制或者其他高级功能,那么你就将需要使用媒体服务器。
寻找适用于你用例的服务器。
我甚至会说,在你的技术栈里选择任何技术之前就从这里开始。
还有一些开源或者商业选择,它们在很多方面都不同。
WebRTC 工作原理问与答
✅ WebRTC 可以用于移动应用吗?
可以。WebRTC 在浏览器和操作系统间(包括 iOS 和 Android)工作。作为开源项目,许多人也将它移植到自己的环境。
✅ 开发 WebRTC 我都需要做什么?
除了支持 WebRTC 的浏览器,你需要安装自己的信令服务器和 TURN 服务器。根据你的用例,也可以使用媒体服务器。
✅ 我在哪里了解更多关于 WebRTC 工作原理的知识?
你可以关注 WebRTC Weekly 和 webrtcHacks,上面的资源非常丰富。也可以访问官方网站(https://webrtc.org/)。
结语
本篇文章的目的是帮助你理解最基础的 WebRTC 知识(如果你是一个新手)。我不想从创建 “hello world” 应用程序开始,你可以在网上找到很多这样的应用。我想做的是带你到更高的地方,让你一览全局。
在很多情况下,人们从一个 “hello world” WebRTC 实现开始,并想要使其适用于他们自己的场景。我发现很多时候这种方法是错误的,因为它依赖于你想要构建的内容(它将决定你的 WebRTC 旅程的起点)。
花些时间阅读这篇文章,然后再阅读一两个 WebRTC 的 “hello world” 手册。如果你能够这样做,你的 WebRTC 实现将会更高效。
更多拓展内容:
https://bloggeek.me/started-learning-webrtc-development/
https://bloggeek.me/webrtcglossary/sdp/
https://bloggeek.me/webrtcglossary/srtp/
https://bloggeek.me/webrtcglossary/sctp/
https://bloggeek.me/webrtcglossary/ice/
https://bloggeek.me/webrtcglossary/trickle-ice/
https://web.dev/promises/
https://bloggeek.me/webrtc-electron-implementations/
https://github.com/coturn/coturn
https://webrtcweekly.com/
https://webrtchacks.com/
作者简介:
Tsahi Levent-Levi:WebRTC 专家,曾为 testRTC 的联合创始人和 CEO,现为 Spearline 公司 testRTC 的产品负责人。Tsahi 拥有多年 WebRTC 技术培训经验,并拥有自己的技术博客 BlogGeek.Me,你可以到这里
(https://webrtccourse.com/)了解和学习他的课程。
致谢:
本文已获得作者 Tsahi Levent-Levi 授权翻译和发布,特此感谢。
本文为澎湃号作者或机构在澎湃新闻上传并发布,仅代表该作者或机构观点,不代表澎湃新闻的观点或立场,澎湃新闻仅提供信息发布平台。申请澎湃号请用电脑访问http://renzheng.thepaper.cn。
- 报料热线: 021-962866
- 报料邮箱: news@thepaper.cn
互联网新闻信息服务许可证:31120170006
增值电信业务经营许可证:沪B2-2017116
© 2014-2024 上海东方报业有限公司