前言
之前在做智能家居网关项目时,用到 WebRTC 技术,使用 C++ 实现了浏览器可以通过 WebRTC 直接观看摄像头的功能。这里分享下之前记录的 WebRTC 的笔记。
什么是 WebRTC
2010 年 5 月,谷歌收购了 Global IP Solutions(简称 GIPS),这是一家专注于 VoIP 和视频会议软件的公司,已开发出 RTC 所需的多项关键组件,如编解码器和回声消除技术。谷歌随后将 GIPS 技术开源,并与 IETF 和 W3C 等标准机构合作,以确保行业共识。2011 年 5 月,谷歌发布了一个名为 WebRTC 的开源项目,旨在实现基于浏览器的实时通信。 它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准。此后,相关协议在 IETF 的标准化工作以及浏览器 API 在 W3C 的标准化工作持续进行。
WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持浏览器或移动应用程序(安卓苹果)进行实时点对点的音频、视频和数据通信的开放标准 API。
WebRTC 的独特之处在于,一旦连接建立,数据便可以直接在浏览器之间实时传输,无需经过服务器。通过绕过服务器,减少了延迟,因为数据不必先发送到服务器,这使得 WebRTC 非常适合用于音频和视频的交换。
WebRTC 如今已嵌入所有现代浏览器中,开发者可以利用 WebRTC 的 JavaScript API 为浏览器用户构建应用程序。当然 WebRTC 现在也被很多编程语言所支持,包括但不限于 C、C++、Go、Java、PHP、JavaScript 等等,因此可以实现跨平台的实时通信方案。
WebRTC 对比 Websocket
与 WebRTC 相似的是 Websocket 协议。WebRTC 和 Websocket 都是用于实时通信,它们的最大区别在于 WebRTC 是点对点通信(可不借助服务器中转流量),而 Websocket 是客户端-服务器模型(需要借助服务器中转流量)。没有了解过 Websocket 的同学可以点击这里查看。
下图是 Websocket 的通信过程
客户端1向客户端2发送hi,首先需要先发送给服务器hi,然后服务器发送hi给客户端2。
而WebRTC 的通信过程如下
客户端1直接点对点发送hi给客户端2,无需经过服务器。这种方式的好处是大大减少一端到另一端所需的时间,同时减轻了服务器的负担和带宽消耗。
WebRTC 用到的协议
-
SRTP (Secure Real-time Transport Protocol)——传输音视频:
- 用于加密、消息认证和完整性检查以保护实时音频和视频流的传输。
-
RTP (Real-time Transport Protocol):
- 用于传输实时媒体数据(音频和视频)的基础协议。
-
RTCP (Real-time Control Protocol):
- 伴随 RTP 工作,用于监控传输统计、QoS(服务质量)管理、同步音视频流等。
-
SCTP (Stream Control Transmission Protocol)——传输数据:
- WebRTC 使用 SCTP 来通过数据通道传输非媒体数据。它支持多流传输和消息排序。
-
DTLS (Datagram Transport Layer Security):
- 用于加密 WebRTC 中的所有数据流,确保传输的安全性。WebRTC 的 DTLS 是基于 UDP 的,因此能够提供低延迟的数据传输。
-
ICE (Interactive Connectivity Establishment):
- 用于通过 NAT 和防火墙找到最佳路径,以便端点之间建立连接。ICE 结合了 STUN 和 TURN 服务器来辅助这一过程。
-
STUN (Session Traversal Utilities for NAT):
- 帮助设备确定其公共 IP 地址并通过 NAT 建立连接。
-
TURN (Traversal Using Relays around NAT):
- 当直接连接不可行时,通过中继服务器转发数据,以确保通信能够进行。
-
SDP (Session Description Protocol):
- 用于在通信双方之间协商会话参数,例如编解码器、媒体类型和网络配置。
WebRTC 的工作流程
WebRTC 的工作流程比 Websocket、HTTP 协议来说相对复杂一些,它用到了很多个协议一起协同工作。
假设有两个对等方,A和B,他们使用WebRTC进行双向媒体流传输(例如,视频聊天应用)。当A想要呼叫B时,具体流程如下:
- 生成SDP Offer:A的应用程序首先需要生成一个SDP Offer。SDP(Session Description Protocol)Offer包含了A应用程序想要建立的会话信息,例如使用的编解码器类型、这是音频还是视频会话等内容。SDP Offer不包括ICE候选,而仅包含会话描述信息。
- 收集ICE候选者:在生成SDP Offer后,A的应用程序会开始收集ICE候选者。为了收集候选者,A的应用程序会向STUN服务器发送请求。STUN服务器返回A的公共IP地址和端口,A的应用程序将这些信息作为候选者添加到ICE候选者列表中。A的应用程序也会收集本地网络的候选信息(如本地IP/端口对)。这些候选者是为了后续的连接性检查。
- 通过信令通道传递SDP Offer:A生成了SDP Offer和相应的ICE候选者列表后,会通过一个信令通道(如HTTPS、WebSocket等)将SDP Offer传递给B的应用程序。需要注意的是,ICE候选者可以在这一步通过信令通道单独传递,通常是在SDP Offer之后或者与Offer一起传输。
- 生成SDP Answer:B的应用程序接收到SDP Offer后,进行以下处理:
- B的应用程序会生成一个SDP Answer,作为对SDP Offer的回应。
- 同时,B的应用程序会收集自己的ICE候选者。类似于A的做法,B会向STUN服务器发出请求并收集公共IP地址/端口,形成自己的候选者列表。
- 通过信令通道传递SDP Answer和ICE候选者:B的应用程序将SDP Answer和自己的ICE候选者列表通过信令通道传递给A的应用程序。
- 连接性检查和媒体传输:在双方互相交换SDP Offer和Answer后,每个应用程序会开始连接性检查。双方应用程序的ICE协议会使用对方提供的候选IP/端口对,发送STUN请求进行连接性验证。如果请求得到了响应,相关的候选者会被认为是有效的,并标记为可用。
- 选择最终的IP/端口对:经过一系列的连接性检查后,A和B将协商并选择一个有效的IP/端口对,用于实际的媒体流传输。
- 使用TURN服务器(如有必要):如果任何一方的应用程序无法找到一个有效的IP/端口对,则会向TURN服务器发送请求,以获取一个公共的中继地址。TURN服务器返回的中继地址将会用于建立连接,并通过信令通道进行交换。
下方是一个直观的通信过程:
整个 WebRTC 通信过程中会用到如下的服务器:
- 信令(Signaling)服务器:用于交换信令信息,WebRTC 没有规定交换信令的方式,一般可用的交换方式是 HTTP、Websocket、MQTT 等等。
- STUN 服务器:帮助客户端发现它们的公共IP地址和NAT类型,并为点对点连接提供网络信息。
- TURN 服务器(可选):在STUN无法穿透NAT或防火墙时,作为中继服务器转发数据流。TURN服务器提供了一种备用机制,确保即使在极为复杂的网络环境下,WebRTC的点对点连接也能够顺利进行。
应用场景
- 统一通信——语音与视频通话,一对一或群组会话
- 观看派对——一起看电视或体育赛事
- 远程医疗、在线教育、法律程序、远程旅行、健身、舞蹈、辅导、教练……——通过远程和虚拟方式进行过去需要面对面进行的垂直化会话
- 远程操作——远程驾驶汽车、叉车、卡车、无人机、船只、潜艇等
- 虚拟与混合活动——在线举办网络研讨会、大型会议及活动
- 云游戏——在云端渲染游戏画面,并实时传输给玩家
- 虚拟空间与元宇宙——在 2D 或 3D 合成渲染的虚拟环境中与人相遇