本页目录
WebRTC
浏览器之间直接传输音视频——WebRTC 用 SDP 协商媒体参数、ICE 打洞穿越 NAT、DTLS-SRTP 加密传输。P2P 的"不经过服务器"是性能优势,也是调试噩梦。
概述
WebRTC(2011)是浏览器内置的实时通信标准,不需要插件就能实现视频通话、屏幕共享和 P2P 数据传输。它组合了多个协议:SDP 做媒体协商、ICE 做 NAT 穿透、DTLS-SRTP 做媒体加密、SCTP 做数据通道。WebRTC 的连接建立是全异步的——candidate 逐个到达、逐个验证——Trickle ICE 大幅减少了连接时间。
架构栈
信令:被故意留白的一环
WebRTC 不规定信令——两端怎么交换 SDP 和 ICE candidate,标准完全不管,由你用 WebSocket/HTTP/任意通道自己实现。这是有意为之:媒体路径要 P2P,但"两个还没连上的人怎么先碰头"本就需要一个双方都能到达的第三方。
先有信令把 offer/answer 递过去,ICE 才有 candidate 可连——这就是 WebRTC 的"先有鸡"。
SDP 协商
Caller → Callee (Offer):
v=0
o=- 1234567890 2 IN IP4 192.168.1.100
s=-
t=0 0
a=group:BUNDLE audio video data ← 同一传输链路上多路复用
m=audio 49170 UDP/TLS/RTP/SAVPF 111 103
c=IN IP4 192.168.1.100
a=rtpmap:111 opus/48000/2
a=rtcp-mux ← RTP 和 RTCP 同一个端口
a=ice-ufrag:8sdf7g
a=ice-pwd:asd88fg
a=fingerprint:sha-256 AB:CD:... ← DTLS certificate hash
Callee → Caller (Answer):
m=audio 49180 UDP/TLS/RTP/SAVPF 111 ← 选定的端口 + codec
...
→ 双方协商完成 → ICE 开始连接检查
ICE
每个 peer 收集三种 candidate:
- host: 本地 IP:port
- srflx (server reflexive): STUN server 返回的公网 IP:port
- relay (relayed): TURN server 分配的中继地址
对每对 (local candidate + remote candidate) 做 connectivity check (STUN binding) → 选出最优可用 pair(优先级 host > srflx > relay,即"能直连就不走中继")。
STUN vs TURN 的分工:STUN 只是"帮你问出自己的公网映射",不转发媒体,几乎零成本;但当两端都在对称 NAT 后、打洞失败时,就必须退到 TURN 中继——所有媒体经它转发,带宽成本高,是部署里唯一绕不开的服务器成本。生产经验:约 10-20% 的连接最终落到 TURN。
Trickle ICE:不必等所有 candidate 收集完才发 offer。candidate 边发现边通过信令发给对端、边做连通性检查,把建连时间从"等最慢的 candidate"压缩到"第一个可用 pair 就绪"——这是 WebRTC 起连快的关键。
DTLS-SRTP
DTLS handshake (类 TLS 1.2 over UDP) → 握手完成后,双方从 DTLS 派生 SRTP 密钥 (不额外交换):
Data Channel
覆盖在 DTLS 上的 SCTP (Stream Control Transmission Protocol):
与 TCP 相比:
- 多 stream (无 HOL blocking)
- 保留消息边界
- 可配置: 可靠 (reliable) / 部分可靠 (timed reliability)
适合: 文件传输, 游戏状态, 聊天
拥塞控制与 Simulcast
实时媒体不能像 TCP 那样靠丢包+重传——一帧的截止时间只有十几毫秒,等重传必然错过。WebRTC 用 GCC (Google Congestion Control):基于 RTP 包到达的延迟梯度预判拥塞(队列在涨 → 早降码率),而非等到真丢包,发送方据此动态调整编码码率。
Simulcast / SVC 解决多人会议的异构带宽:同一路摄像头同时编出多档(如 180p/360p/720p),由中间服务器按每个接收端的网络分别下发合适的一档——这正是下面 SFU 能"按人选档"的前提。
SFU / MCU / Mesh — 多人拓扑
WebRTC 本是 P2P,但多人时 P2P 不可扩展,必须引入服务器。三种拓扑(与流媒体协议里的分发权衡同源):
为何 WebRTC 难像 HLS 那样铺 CDN:每条连接有状态(ICE/DTLS/SRTP 上下文 + 实时拥塞反馈),不是可缓存的文件。规模化只能靠 SFU 级联,而非边缘缓存——这是"亚秒实时"换来的根本代价。
参考
- webrtc.org: webrtc.googlesource.com
- 工具:
chrome://webrtc-internals
Keywords: WebRTC, signaling, SDP, ICE, Trickle ICE, STUN, TURN, DTLS-SRTP, SCTP, Data Channel, GCC, simulcast, SVC, SFU, MCU, mesh, Opus