核心协议族速查
WebRTC 不是一个协议,是一组协议的胶水层。下面这张表是工程上"哪一层出问题该看什么 RFC"的速查。
1. 协议地图
┌──────────────────────────────────────────────────────────────┐
│ 应用层 MediaStream / RTCPeerConnection / RTCDataChannel │
├──────────────────────────────────────────────────────────────┤
│ 协商层 SDP (RFC 8866) + JSEP (RFC 8829) │
├──────────────────────────────────────────────────────────────┤
│ 媒体层 RTP/RTCP (RFC 3550) + SRTP (RFC 3711) │
│ 编解码: Opus/G.722 音 · VP8/VP9/H.264/AV1 视 │
├──────────────────────────────────────────────────────────────┤
│ 数据层 SCTP (RFC 4960) over DTLS │
├──────────────────────────────────────────────────────────────┤
│ 安全层 DTLS 1.2/1.3 (RFC 6347/9147) │
├──────────────────────────────────────────────────────────────┤
│ 穿透层 ICE (RFC 8445) + STUN (RFC 8489) + TURN (RFC 8656) │
├──────────────────────────────────────────────────────────────┤
│ 传输层 UDP (主) / TCP+TLS (兜底) │
└──────────────────────────────────────────────────────────────┘
2. 每个协议的职责与失败现象
| 协议 | 职责 | 典型失败现象 |
|---|---|---|
| SDP | 描述会话能力(codec、SSRC、扩展头、加密参数) | setRemoteDescription 报错;m-line 数量不匹配 |
| JSEP | 规范 Offer/Answer 状态机 | glare 时 setLocalDescription 失败 |
| ICE | 在多对候选地址中找到一条可达路径 | iceConnectionState: failed,永远 checking |
| STUN | 让端点知道自己的公网 IP:port | srflx 候选缺失,只能拿到 host |
| TURN | 在两端都打不通时做中继 | 关键的兜底;不部署=对称 NAT 全失败 |
| DTLS | 在 UDP 上做 TLS 握手,导出 SRTP 密钥 | DTLS 握手超时;证书指纹不匹配 |
| SRTP | 加密、鉴权 RTP 媒体包 | 解密失败,对端收到全黑画面 |
| SCTP | DataChannel 的传输层,提供可靠/不可靠 | RTCDataChannel.send 抛 InvalidStateError |
| RTP/RTCP | 媒体打包、时序、反馈 | 序号乱、PLI 不响应导致花屏 |
3. ICE:连通性建立的核心
目标:在两端各自能列出的所有"地址候选"中,找到至少一条双向连通的。
候选优先级(高→低):
host (本机 IP)
↓
srflx (STUN 反射映射)
↓
prflx (peer-reflexive,连通性检查中发现)
↓
relay (TURN 中继,UDP > TCP > TLS)
Trickle ICE(RFC 8838)让候选边收集边发送,建连时间从几秒降到几百毫秒。生产必开。
ICE Restart:当网络发生切换(4G ↔ Wi-Fi、IP 变更),调用 pc.restartIce() 重新跑一遍 ICE,不重新协商 SDP。Chrome 76+ / Safari 14+ 支持。
4. STUN vs TURN:什么时候必须 TURN
| NAT 类型 | STUN 可穿透? | TURN 必要? |
|---|---|---|
| Full Cone | ✅ | 否 |
| Restricted Cone | ✅ | 否 |
| Port Restricted Cone | 多数 ✅ | 否 |
| Symmetric NAT | ❌ | 必须 |
| 运营商级 NAT(CGNAT) | ❌ | 必须 |
| 企业防火墙仅放行 443 | ❌ | TURN over TLS:443 |
经验数据:互联网公网用户约 10%~20% 会落到对称 NAT 或严格防火墙后面,不部署 TURN 就等于现网失败率 15%。
5. SDP:能力描述的"配置文件"
SDP 不是协议,是一种格式。WebRTC 用它做能力声明:
v=0
o=- 4611733054762309635 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS stream-id
m=audio 9 UDP/TLS/RTP/SAVPF 111 103
a=rtpmap:111 opus/48000/2
a=fingerprint:sha-256 4A:AD:...
a=setup:actpass
a=ice-ufrag:abcd
a=ice-pwd:1234567890...
a=mid:0
a=sendrecv
m=video 9 UDP/TLS/RTP/SAVPF 96 97
a=rtpmap:96 VP8/90000
a=rtpmap:97 H264/90000
a=fmtp:97 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=mid:1
a=sendrecv
详细字段拆解见 SDP结构详解.md。
6. DTLS-SRTP:为什么浏览器强制加密
旧的 SDES(在 SDP 里明文交换密钥)已被废弃。WebRTC 强制:
- 每端生成自签名证书。
- 证书 SHA-256 指纹通过 SDP 交换(信令通道可信靠 HTTPS)。
- DTLS 握手中校验对方证书指纹。
- 从 DTLS master secret 通过
srtp_aes128_cm_sha1_80等套件派生 SRTP 密钥。
这意味着信令通道被劫持也无法窃听媒体——只要指纹是端点自己生成的,中间人无法伪造。
E2EE(端到端加密,超过 SFU 也无法解密)需要额外的 Insertable Streams 或 SFrame,见 06-安全与合规。
7. RTP / RTCP:媒体传输与反馈
RTP 负责打包,RTCP 负责控制反馈。WebRTC 必用的 RTCP 反馈:
| 反馈 | 用途 | 触发 |
|---|---|---|
| NACK | 请求重传单个 RTP 包 | 接收端检测序号丢失 |
| PLI (Picture Loss Indication) | 请求关键帧 | 解码失败、新订阅者加入 |
| FIR (Full Intra Request) | 请求关键帧(强力版) | 同上,PLI 失败 |
| REMB | 估计带宽(已被 TWCC 取代) | 老浏览器兼容 |
| TWCC | 传输层全链路拥塞反馈 | 现代浏览器默认 |
8. SCTP:DataChannel 的传输层
| 配置 | 语义 | 类似于 |
|---|---|---|
ordered: true, maxRetransmits: null | 可靠 + 有序(默认) | TCP |
ordered: false, maxRetransmits: 0 | 不可靠 + 无序 | UDP |
ordered: true, maxPacketLifeTime: 100 | 部分可靠,100ms 内重传 | 兼顾延迟与丢包 |
实时游戏的状态广播用第二种,文件传输用第一种。
9. RFC 速查表
| 主题 | RFC | 标题 |
|---|---|---|
| 整体架构 | RFC 8825 | Overview: Real-Time Protocols for Browser-Based Applications |
| JSEP | RFC 8829 | JavaScript Session Establishment Protocol |
| SDP | RFC 8866 | SDP: Session Description Protocol |
| ICE | RFC 8445 | Interactive Connectivity Establishment |
| Trickle ICE | RFC 8838 | Trickle ICE |
| STUN | RFC 8489 | Session Traversal Utilities for NAT |
| TURN | RFC 8656 | Traversal Using Relays around NAT |
| DTLS 1.2 | RFC 6347 | Datagram Transport Layer Security 1.2 |
| DTLS 1.3 | RFC 9147 | Datagram Transport Layer Security 1.3 |
| SRTP | RFC 3711 | The Secure Real-time Transport Protocol |
| DTLS-SRTP 密钥派生 | RFC 5764 | DTLS Extension for SRTP Key Establishment |
| RTP | RFC 3550 | RTP: A Transport Protocol for Real-Time Applications |
| TWCC | draft-holmer-rmcat-transport-wide-cc-extensions | Transport-wide Congestion Control |
| WHIP | RFC 9725 | WebRTC-HTTP Ingestion Protocol |
| WHEP | draft-ietf-wish-whep | WebRTC-HTTP Egress Protocol |
核对日期:2026-06-22。WHEP 在 2026 年仍是 draft 状态,关注 datatracker 的更新。