WebRTC(Web Real-Time Communication)
- 让浏览器和移动应用能够直接进行实时通信,而无需借助中间服务器。
- 这种通信包括视频通话、语音聊天以及文件共享等。
- WebRTC 的核心优势在于它的点对点(P2P)连接能力,这大大降低了延迟,提高了通信效率。
原理
虽然 WebRTC 目标是实现 P2P 连接,但建立连接过程仍需要一些服务器的协助。
- 信令(Signaling):这是 WebRTC 连接建立的第一步,也是至关重要的一步。由于 WebRTC 规范没有定义信令的具体方式,开发者可以自由选择任何信令机制(例如 WebSocket、XHR、SIP 等)。2 类主要信令:
- 会话描述协议(SDP):SDP 是一种文本协议,用于描述媒体会话的参数,如媒体类型(音频/视频)、编码器、IP 地址、端口等。通信双方通过 SDP 协商媒体的格式和能力。
- ICE 候选者(ICE Candidates):ICE(Interactive Connectivity Establishment)是一种用于发现和建立 P2P 连接的方法。ICE 候选者是客户端可以用来进行通信的 IP 地址和端口的组合。这包括
- 主机候选者(本地 IP 地址)—— 设备在本地网络中的真实 IP 地址和端口,如果两个设备在同一个局域网内,或者都没有经过 NAT,那么直接使用主机候选者就可以建立连接。
- 反射候选者(通过 STUN 服务器获取的公网 IP 地址和端口)—— 当你的设备通过一个 STUN 服务器请求自己的公网 IP 地址和端口时,STUN 服务器会返回你的设备从互联网上看起来的地址 —— 大多数情况都是这种。
- **中继候选者(通过 TURN 服务器获取的地址) **—— 如果 STUN 服务器也无法帮助你建立直接连接(例如,遇到严格的对称型 NAT,或者防火墙太严格),那么就需要一个 TURN 服务器作为中继。你的设备会向 TURN 服务器请求一个地址,所有的数据都会通过 TURN 服务器转发。
- NAT 穿越(NAT Traversal):**WebRTC 连接最常见的挑战是网络地址转换(NAT)。由于大多数设备都处于 NAT 后面,无法直接从外部访问。**WebRTC 通过以下方式解决 NAT 穿越问题:
- STUN(Session Traversal Utilities for NAT)服务器:STUN 服务器帮助客户端发现自己的公网 IP 地址和端口。客户端向 STUN 服务器发送请求,服务器返回客户端从互联网上看到的 IP 地址和端口。
- TURN(Traversal Using Relays around NAT)服务器:如果 STUN 无法建立直接连接(例如,遇到对称型 NAT),TURN 服务器就会作为中继服务器。所有数据都通过 TURN 服务器转发,虽然会增加一些延迟,但能确保连接成功。
一旦 P2P 连接建立,媒体数据(音频和视频)就可以直接在浏览器之间传输。WebRTC 使用以下协议进行媒体传输:
- RTP(Real-time Transport Protocol):RTP 是用于实时数据传输的协议,它提供时间戳、序列号等信息,确保媒体流的顺序和同步。
- RTCP(RTP Control Protocol):RTCP 与 RTP 协同工作,用于监控 RTP 会话的质量、提供拥塞控制、报告发送和接收统计信息等。
- SRTP(Secure Real-time Transport Protocol):为了保证通信安全,WebRTC 对所有媒体数据进行加密。SRTP 是 RTP 的安全扩展,它提供了加密、消息认证和重放保护等功能。
many-to-many
多对多通信广泛使用在线上会议、多人游戏等场景,在 WebRTC 出现之前,多对多通讯基本要基于 CS 架构开发独立的 APP,各家开发不同的协议栈来实现。也有基于浏览器的,但都是要用 Adobe 的 Flash 插件来实现。
WebRTC 出现之后,提供了一个基于浏览器的 BS 架构、帮助开发者搞定了 NAT 穿透的平台,极大地标准化了浏览器内的实时通信能力,并提供了一套开放、免费且无需插件的解决方案,这彻底改变了实时通信的格局。它将复杂的底层网络和媒体处理细节抽象化,使得更多的开发者能够轻松地构建实时音视频应用。
以下架构是多对多通信的几个解决方案,加上 WebRTC,相辅相成:
- 全连接网格(Full Mesh / P2P Mesh):每个参与者都与其他所有参与者建立一个独立的 WebRTC PeerConnection。
- 选择性转发单元(SFU - Selective Forwarding Unit)
- 每个参与者只与 SFU 服务器建立一个 PeerConnection。
- 参与者将自己的音视频流发送到 SFU 服务器。
- SFU 服务器接收所有参与者的流,然后根据需要,选择性地将这些流转发给其他参与者,而不做任何媒体处理(如解码、混流)。
- 多点控制单元(MCU - Multipoint Control Unit)
- 每个参与者也只与 MCU 服务器建立一个 PeerConnection。
- 参与者将自己的音视频流发送到 MCU 服务器。
- MCU 服务器会解码所有接收到的音视频流,将它们混合(Mixing)成一个或几个新的流,然后再将混合后的流发送给每个参与者。
Full Mesh 全分布式,不需要中心服务器,但仅适用于少数参与者的场景,否则节点的上下行流量都会暴增。SFU 是最流行的,中心服务器做个转发,还能适当加入控制,比如权限控制。MCU 需要较多的服务器算力,Mix 在服务器上做,适合一个固定团队或公司内,不太适合公网上规模变化较大场景。
组织
WebRTC 是一个开放标准,得到了多个重要组织和公司的支持与推动:
- W3C (World Wide Web Consortium): 负责定义 WebRTC 的 JavaScript API 和相关的 Web 标准。
- IETF (Internet Engineering Task Force): 负责定义 WebRTC 底层传输协议(如 ICE, STUN, TURN, RTP, SRTP, SCTP)的技术规范。
- Google: 作为 WebRTC 项目的主要发起者和贡献者,Google 在其 Chrome 浏览器中积极推广和实现了 WebRTC。
- Mozilla: Firefox 浏览器的开发者,也是 WebRTC 的重要支持者和实现者。
- Apple: Safari 浏览器的开发者,也在其浏览器中实现了 WebRTC。
- Microsoft: Edge 浏览器的开发者,同样支持 WebRTC。
- 其他公司: 许多实时通信技术公司、会议服务提供商和开发者社区都积极参与 WebRTC 的发展和应用。
开源库
服务器端框架/媒体服务器
- SFU (Selective Forwarding Unit) / MCU (Multipoint Control Unit) 服务器:
- Janus WebRTC Server: 一个多功能的 WebRTC 服务器,采用插件式架构,支持多种用例,包括视频会议、流媒体、SIP 网关等。
- Jitsi Meet / Jitsi Videobridge: Jitsi 是一个非常成熟和广泛使用的开源视频会议解决方案,其核心是 Jitsi Videobridge (一个 SFU)。
- mediasoup: 一个高性能的 WebRTC SFU,专注于提供高质量的视频流,并支持 Simulcast 和 SVC。通常与 Node.js 或 Rust 应用程序集成。
- Kurento Media Server: 一个功能强大的 WebRTC 媒体服务器,提供媒体传输、处理、录制和回放功能,并支持计算机视觉等高级功能。
- Ant Media Server: 一个可扩展的实时流媒体服务器,支持 WebRTC、RTMP、HLS 等多种协议。
- LiveKit: 一个相对较新的开源实时音视频平台,提供 SFU 服务和多平台 SDK。
- 信令服务器框架
客户端 SDK/库
- JavaScript 封装库:
- adapter.js: 这是一个由 Google WebRTC 团队维护的 shim (垫片) 库,用于弥合不同浏览器 WebRTC 实现之间的差异,使开发者可以使用统一的 API。
- SimpleWebRTC: 一个流行的 JavaScript 库,提供了高层次的 API,简化了音频/视频通话、屏幕共享和文件传输的实现。
- PeerJS: 另一个广受欢迎的库,提供简单的 API 来设置点对点连接和数据交换,处理了信令、连接管理和数据传输的复杂性。
- Socket.io: 虽然不是专门的 WebRTC 库,但它是一个流行的实时 Web 框架,经常与 WebRTC 结合使用进行信令。
- RTCMultiConnection.js: 一个功能丰富的 WebRTC JavaScript 库,用于构建多对多应用程序(屏幕共享、音视频会议、文件共享等)。
- simple-peer: 一个轻量级的 WebRTC 抽象层,适用于 Node.js 和浏览器,简化了 PeerConnection 的使用。
- 移动端和桌面端 SDK:
- WebRTC Native Library (Google libwebrtc): 这是 WebRTC 项目的官方 C++ 实现,通常用于构建 Android、iOS 和桌面应用程序。许多其他移动或桌面 WebRTC SDK 都是基于这个核心库构建的。
- React Native WebRTC: 用于在 React Native 应用中集成 WebRTC 功能。
- Flutter WebRTC: 用于在 Flutter 应用中集成 WebRTC 功能。
- Pion (Go): 一个用 Go 语言编写的 WebRTC 栈,常用于构建 WebRTC 服务器或 Go 语言的客户端应用。
- aiortc (Python): 基于 Python asyncio 的 WebRTC 和 ORTC 实现。