WebRTC 全景实战 (0):架构全景与协议栈地图
"WebRTC 不是某一个 API,而是一整套让浏览器能够安全、低延迟地交换实时媒体的开放标准。"
如果你曾经尝试在网页里做视频通话,大概率遇到过这样的困惑:RTCPeerConnection 的文档能看懂,但 ICE 一直 failed;SDP 里一堆 a=rtpmap 不知道在协商什么;明明本地预览正常,对方却听不到声音。
这些问题的根源,通常不是某个 API 调用错了,而是缺少一张 WebRTC 协议栈的全景地图。
本系列 WebRTC 全景实战 共 16 篇,将从架构认知出发,逐层深入到信令、SDP、ICE、DTLS/SRTP、RTP/RTCP、编解码、拥塞控制、SFU 架构与生产部署,每篇均配套 examples/webrtc-lab 实战代码。本文作为第零章,回答最根本的问题:WebRTC 是什么?它从哪来?它由哪些层组成?
本篇术语表(系列总纲)
后续各章会重复出现这些概念,建议先建立整体认知:
| 术语 | 英文 | 解释 |
|---|---|---|
| WebRTC | Web Real-Time Communication | W3C + IETF 联合定义的浏览器实时通信标准栈,不是某个 npm 包或单一 SDK |
| W3C | World Wide Web Consortium | 定义浏览器 JavaScript API(getUserMedia、RTCPeerConnection 等) |
| IETF | Internet Engineering Task Force | 定义底层协议(ICE、DTLS、SRTP、RTP、SCTP 等 RFC) |
| P2P | Peer-to-Peer | 两个或多个端点直接交换媒体,不经过中央媒体服务器 |
| SFU | Selective Forwarding Unit | 选择性转发单元:服务端转发 RTP 包但不转码,见 Ch12 |
| MCU | Multipoint Control Unit | 多点控制单元:服务端混流/转码后分发,CPU 开销大 |
| Signaling | 信令 | WebRTC 标准外的控制通道,用于交换 SDP 和 ICE Candidate |
| SDP | Session Description Protocol | 文本格式的会话「合同」,描述 Codec、ICE 参数、DTLS 指纹 |
| ICE | Interactive Connectivity Establishment | 在多条网络路径中选择最优 UDP 通道的算法 |
| STUN | Session Traversal Utilities for NAT | 帮助客户端发现公网 IP:Port 的协议 |
| TURN | Traversal Using Relays around NAT | NAT 穿透失败时的中继服务器协议 |
| DTLS | Datagram Transport Layer Security | UDP 上的 TLS,用于密钥协商 |
| SRTP | Secure RTP | 加密的 RTP 媒体传输 |
| RTP/RTCP | Real-time Transport / Control Protocol | 媒体数据面与控制反馈协议,1996 年标准化 |
| JSEP | JavaScript Session Establishment Protocol | Offer/Answer 协商模型,RFC 8829 |
| MBONE | Multicast Backbone | 1990 年代 Internet 多播实验网络,WebRTC 前身工具的运行环境 |
| NPAPI | Netscape Plugin API | 已废弃的浏览器插件接口,Gmail 视频聊天曾依赖它 |
系列学习路线图
| Phase | 章节 | 核心能力 | 配套 Lab |
|---|---|---|---|
| 1 | Ch0–2 | 建立全局地图,跑通第一个 P2P | ch01-media-devices, ch02-p2p-basic |
| 2 | Ch3–6 | 理解连接建立的每一层 | signaling/, coturn |
| 3 | Ch7–9 | 媒体加密、传输、编解码 | Wireshark 抓包 |
| 4 | Ch10–12 | 拥塞控制、Simulcast、SFU | LiveKit / Pion |
| 5 | Ch13–15 | 生产排障、部署、Capstone | 完整视频会议 |
一、历史脉络:从 MBONE 到浏览器
理解 WebRTC 的设计,需要理解它站在哪些协议之上、又为什么放弃了哪些旧路。本节参考 WebRTC for the Curious — 历史 中协议作者与 Google 早期团队的访谈,梳理关键转折。
1.1 时间线:四十年实时通信演进
1.2 RTP 的诞生:从「工具」到「协议」
RTP 共同作者 Ron Frederick 在 1992 年基于 Sun VideoPix 帧采集卡编写 nv 网络视频会议工具,目标是在 128 kbps ISDN 带宽下传输可接受画质——为此他实现了专用软件视频压缩(后获专利 US5485212A),并在 MBONE(Internet 多播主干网)上向全球广播 IETF 会议。
nv、vat 等早期工具各自有轻量会话协议。IETF 工作组(Van Jacobson、Steve Casner、Henning Schulzrinne 等)的目标不是再做一个工具,而是提炼所有工具可共用的媒体传输基础——这就是 RTP/RTCP(后修订为 RFC 3550)。
Ron Frederick 在访谈中反思:RTP 在单播场景下 RTCP 显得过于复杂;许多人转向 TCP/HTTP 流式传输因为「足够好」。但 TCP 多方通话需向每个对等方重复发送相同数据,带宽效率骤降——这正是 WebRTC 坚持 UDP + RTP 的原因。
1.3 为什么 WebRTC 是单播,不是 IP 多播?
| 维度 | IP 多播(MBONE 时代) | WebRTC 单播 + SFU |
|---|---|---|
| 网络要求 | 全网/router 支持多播 | 标准互联网即可 |
| 服务端 | 极简(多播代转发) | 需要 SFU/TURN |
| 运营商 | 几乎不部署多播 | 完全兼容 |
| 安全 | 难以 per-user 加密 | DTLS/SRTP 原生支持 |
Marratech(后被 Google 收购)早期也押注多播——「网络帮你把包传给所有人,服务器可以非常简单」。但行业最终转向 packet shufflers(SFU),因为公网多播从未规模化部署。WebRTC 的设计选择是现实主义的:在现有互联网上工作,而非等待网络升级。
1.4 WebRTC 诞生:Google 的三重动机
Google 产品经理 Serge Lachapelle(Marratech 联合创始人)在 Curious 访谈 中总结了 WebRTC 诞生的背景:
Gmail 语音视频聊天(WebRTC 前身)的教训:Justin Uberti 将 GIPS(音频)、Vidyo(视频)、libjingle(网络)三个子系统拼在一起——每个都为不同问题设计,API 完全不同。WebRTC 的目标就是一次性解决这些集成痛点,让开发者专注业务。
刻意不标准化信令:SIP 等已有方案存在,重新标准化信令「不会创造有价值贡献」,反而可能演变为政治问题。因此 WebRTC 只标准化媒体通道,信令留给应用层——这也是 Ch3 必须自己写 WebSocket 服务器的根本原因。
1.5 从 NPAPI 插件到沙盒化浏览器
| 阶段 | 技术栈 | 问题 |
|---|---|---|
| Gmail 视频聊天 | GIPS + Vidyo + libjingle + NPAPI | 三套 API、插件安全风险 |
| Chrome 原生 WebRTC | 统一栈 + 沙盒进程 | 默认加密、无插件依赖 |
| W3C Recommendation | 跨浏览器标准 API | Firefox/Safari 独立实现 |
Justin Uberti(Google 工程师,后领导 WebRTC 团队)在整合 Gmail 视频聊天时的核心贡献,是把三个异构子系统拼成一个可用的产品——这段「集成噩梦」直接催生了「一次性解决所有集成问题」的 WebRTC 目标。
1.6 Maastricht 2010:跨公司午餐会
2010 年夏天,在荷兰 Maastricht 的一次非正式午餐会上,Google、Cisco、Ericsson、Skype、Mozilla、Linden Labs 等公司的工程师聚在一起讨论「浏览器里的实时通信应该是什么样」。档案可在 rtc-web.alvestrand.com 查阅。
这次会议的意义:
- 跨厂商共识:不是 Google 一家说了算,而是行业共同方向
- Skype 贡献 Opus:Skype 已在 IETF 完成 Opus 音频 Codec 标准化,为 WebRTC 音频奠定基础
- Harald Alvestrand 启动 IETF 流程:Google 的 Harald 此前已有丰富 IETF 经验,推动 RTCWeb 工作组
二、WebRTC 解决什么问题
2.1 实时通信 vs 流媒体
| 维度 | WebRTC | WebSocket + HLS/DASH |
|---|---|---|
| 传输 | UDP 为主(RTP over DTLS) | TCP(HTTP) |
| 延迟 | 100–300ms 级 | 3–30s(分片缓冲) |
| 交互 | 双向、多路、可 P2P | 主要是单向拉流 |
| 典型场景 | 视频会议、连麦、远程桌面、AI 语音 | 直播观看、点播 |
WebRTC 的核心价值是:在不可控的公网环境下,让两个或多个端点之间建立低延迟、加密的实时媒体通道。
2.2 三代 RTC 架构演进
| 架构 | 工作方式 | 延迟 | 服务端 CPU | 适用规模 |
|---|---|---|---|---|
| Full Mesh P2P | 每对参与者直连 | 最低 | 无媒体处理 | ≤4 人 |
| MCU | 服务端混流后分发 | 较高 | 极高(转码) | 传统电话会议 |
| SFU | 服务端选择性转发,不转码 | 低 | 低且可预测 | 10–10,000+ 人 |
本系列前半段聚焦 P2P 原理(Ch1–Ch6),后半段进入 SFU 生产架构(Ch10–Ch15)。理解 P2P 是理解 SFU 的基础——SFU 本质上是在帮每个参与者维护多条「逻辑上的 P2P 订阅关系」。
2.3 WebRTC 不适用场景
| 场景 | 为何不适合 | 替代方案 |
|---|---|---|
| 万人单向直播 | P2P/SFU 无法支撑分发规模 | HLS/DASH + CDN |
| 高延迟可接受 | WebRTC 复杂度不值得 | WebSocket + 预录流 |
| 仅文本聊天 | 杀鸡用牛刀 | WebSocket / SSE |
| 需要服务端录制混流 | 需额外 Egress 组件 | LiveKit Egress / FFmpeg |
三、W3C 与 IETF:两套标准的分工
关键理解:你在 JavaScript 里调用的是 W3C API;浏览器内部(C++)实现 IETF 协议。你不需要手动构造 RTP 包或 DTLS 握手——但需要理解这些层在做什么,才能 Debug。
四、WebRTC 协议栈全景
WebRTC 由 W3C(浏览器 API)和 IETF(底层协议)两套标准共同定义。RFC 8825 是总览文档,推荐阅读。
4.1 各层职责速查
| 层级 | 标准 | 职责 |
|---|---|---|
| Signaling | 无标准(应用自定义) | 交换 SDP、ICE Candidate、Room 状态 |
| JSEP | RFC 8829 | Offer/Answer 协商模型 |
| SDP | RFC 8866 | 会话描述:编解码器、端口、ICE 参数 |
| ICE | RFC 8445 | 在多条网络路径中选最优连通路径 |
| STUN | RFC 5389 | 发现公网 IP/端口 |
| TURN | RFC 5766 | NAT 穿透失败时的中继 |
| DTLS | RFC 6347 | UDP 上的 TLS,密钥协商 |
| SRTP | RFC 3711 | 媒体流加密 |
| SCTP | RFC 8831 | Data Channel 多路复用 |
| RTP/RTCP | RFC 3550 | 媒体包传输与 QoS 反馈 |
Signaling 不在 WebRTC 标准内。 浏览器 API 只负责建立连接,你必须自己实现信令通道(WebSocket 最常见)来交换 SDP 和 ICE Candidate。这是新手第一个坑。
4.2 W3C API 与 IETF 协议对照
| 你写的代码 | 触发的协议行为 |
|---|---|
getUserMedia() | 捕获 MediaStreamTrack,不涉及网络 |
pc.addTrack() | 创建 RTCRtpSender,SDP 中出现新 m-line |
pc.createOffer() | 生成 SDP Offer(JSEP) |
pc.setLocalDescription() | 开始 ICE Gathering |
pc.onicecandidate | 产出 ICE Candidate |
pc.setRemoteDescription() | 开始 ICE Connectivity Check |
pc.createDataChannel() | 协商 SCTP over DTLS |
4.3 协议层依赖关系
4.4 完整 RFC 索引(本系列引用)
| RFC | 标题 | 对应章节 |
|---|---|---|
| 8825 | WebRTC Overview | Ch0 |
| 8829 | JSEP | Ch2, Ch4 |
| 8866 | SDP | Ch4 |
| 8445 | ICE | Ch5 |
| 5389 | STUN | Ch5 |
| 5766 | TURN | Ch5, Ch14 |
| 6347 | DTLS | Ch7 |
| 5764 | DTLS-SRTP | Ch7 |
| 3711 | SRTP | Ch7 |
| 8827 | WebRTC Security | Ch7 |
| 3550 | RTP/RTCP | Ch8 |
| 7587 | Opus | Ch9 |
| 8831 | Data Channels | Ch6 |
五、一次 P2P 通话的完整时序
在写任何代码之前,先理解端到端流程(信令用 WebSocket 举例):
Phase 1(Ch1–Ch2)将实现这个流程;Phase 2(Ch3–Ch6)将把每一步拆解开。
5.1 连接建立四阶段
| 阶段 | 成功标志 | 失败常见原因 |
|---|---|---|
| 信令 | Offer/Answer 交换完成 | WebSocket 断开、SDP 格式错误 |
| ICE | iceConnectionState=connected | NAT 对称、无 TURN |
| DTLS | connectionState=connected | fingerprint 不匹配 |
| SRTP | ontrack 触发、有画面 | Codec 无交集、防火墙 |
六、适用场景与选型建议
| 场景 | 推荐架构 | 本系列对应章节 |
|---|---|---|
| 1v1 视频通话 | Full Mesh P2P | Ch2 |
| 3–8 人会议 | SFU | Ch12 |
| 大型直播(万人观看) | CDN + 可选连麦 SFU | Ch11, Ch12 |
| 实时白板 / 游戏状态 | Data Channel | Ch6 |
| AI 语音助手 | SFU + Agent 框架 | Ch15 + LiveKit 介绍 |
| 纯单向直播 | HLS/WebRTC 推流 Ingress | 超出本系列,参考 LiveKit Ingress |
七、常见误解 FAQ
| 误解 | 真相 |
|---|---|
| 「WebRTC 是 P2P,不需要服务器」 | 需要信令服务器;多数场景还需要 TURN 和 SFU |
| 「WebRTC 可以替代 WebSocket」 | WebSocket 适合信令和控制;WebRTC 适合低延迟媒体 |
| 「只要 getUserMedia 就能视频通话」 | 还需要 PeerConnection + 信令 + ICE |
| 「WebRTC 完全免费」 | 开源免费,但 TURN 带宽、SFU 服务器有运维成本 |
| 「所有浏览器 WebRTC 行为一致」 | 有差异,建议用 adapter.js |
| 「Simulcast 是 WebRTC 标准」 | Simulcast 是广泛部署的扩展,SFU 必须支持 |
八、实战 Lab:打开调试工具
本篇无需写代码,但请完成以下准备:
- 使用 Chrome 打开
chrome://webrtc-internals - 访问 WebRTC Samples 建立一个测试连接
- 在 webrtc-internals 中观察:
RTCPeerConnection列表- ICE candidate pair 状态
- Stats 面板中的
inbound-rtp/outbound-rtp
这些面板将在 Ch13 成为生产排障的核心工具。
8.1 webrtc-internals 观察清单
| 观察项 | 位置 | 说明 |
|---|---|---|
| PeerConnection 列表 | 首页 | 每个 Tab 一个 PC |
| ICE candidate pair | ICE 标签 | state=succeeded 的行 |
| Local/Remote SDP | SDP 标签 | 对比 Offer/Answer |
| Stats graphs | Graphs 标签 | 码率、丢包实时曲线 |
| getUserMedia | 媒体标签 | 采集分辨率与帧率 |
九、本章小结与下一篇预告
| 维度 | 核心要点 |
|---|---|
| 定位 | 浏览器端低延迟、加密、P2P 实时媒体框架 |
| 标准 | W3C 定义 API,IETF 定义协议栈 |
| 关键层 | Signaling → JSEP/SDP → ICE → DTLS → SRTP → Codec |
| 架构 | P2P 适合小规模;SFU 是生产会议的主流 |
| 学习路径 | 先跑通 P2P,再深入每层协议,最后上 SFU |
下一篇(Ch1) 我们从最顶层 API 开始:getUserMedia 如何获取摄像头和麦克风,如何切换设备和处理权限。
系列导航
章节 主题 状态 0 架构全景与协议栈地图 ✅ 已发布 1 浏览器媒体 API 与设备管理 ✅ 已发布 2 第一个 P2P 视频通话 ✅ 已发布 3 信令服务器设计与会话状态机 ✅ 已发布 4 SDP 解剖与媒体协商 ✅ 已发布 5 ICE、STUN、TURN 与 NAT 穿透 ✅ 已发布 6 Data Channel 与 SCTP over DTLS ✅ 已发布 7 DTLS 握手与 SRTP 加密体系 ✅ 已发布 8 RTP/RTCP 媒体传输与 QoS ✅ 已发布 9 音视频编解码与 Simulcast 入门 ✅ 已发布 10 带宽估计与拥塞控制 GCC ✅ 已发布 11 Simulcast、SVC 与选择性订阅 ✅ 已发布 12 SFU/MCU/Mesh 架构与 Pion 实战 ✅ 已发布 13 调试工具链与可观测性 ✅ 已发布 14 TURN 集群部署与多区域扩展 ✅ 已发布 15 Capstone 生产级视频会议系统 ✅ 已发布
References
- RFC 8825 — Overview: Real-Time Protocols for Browser-Based Applications
- W3C WebRTC Recommendation
- WebRTC for the Curious — 历史(含 RTP/WebRTC 作者访谈)
- WebRTC for the Curious — Introduction
- Maastricht 2010 RTC-Web 午餐会档案
- MDN — WebRTC API
- webrtc.org — Getting Started
- High Performance Browser Networking — WebRTC (Ilya Grigorik)