2、WebRTC核心架构:P2P通信模型、信令与媒体流分离、NAT穿透与ICE框架、SDP协商机制
WebRTC 的架构设计,说白了就是一套「让浏览器之间能直接通话」的工程方案。我最早接触它的时候,觉得这东西简直像变魔术——两个在不同内网里的浏览器,怎么就能互相传视频呢?后来拆开一看,其实核心就四块:P2P 模型、信令与媒体分离、NAT 穿透、SDP 协商。咱们一个一个聊。
2.1 P2P 通信模型:为什么非要「点对点」?
传统的视频通话,通常是客户端-服务器模式。你说话,声音先到服务器,服务器再转发给对方。这模式简单,但服务器带宽成本高得吓人。我见过一个创业团队,用户量刚破万,服务器带宽费就占了营收的 60%。
WebRTC 走的是 P2P 路线。说白了,就是你的浏览器直接连对方的浏览器,数据不经过中间服务器。好处很明显:
- 延迟低:少跳一次网络,延迟能降 30-50ms
- 成本省:服务器只负责「牵线」,不负责「传话」
- 隐私好:数据不落地,加密传输
但 P2P 也有坑。我在项目中遇到过一个问题:两个用户都在对称 NAT 后面,直接连根本连不上。这时候就得靠 TURN 服务器做中继了。嗯,这里要注意——P2P 是理想,实际场景里经常退化成 TURN 中继。
核心要点:WebRTC 优先尝试 P2P,失败后自动降级为 TURN 中继。开发者不需要手动干预,ICE 框架会帮你搞定。
2.2 信令与媒体流分离:为什么非要「分家」?
WebRTC 有一个设计让很多人困惑:它把「信令」和「媒体流」完全分开。信令走你自己搭的服务器(WebSocket、HTTP 都行),媒体流走 P2P 通道。
为什么会这样?我个人的理解是:WebRTC 不想替开发者决定用什么信令协议。你想想看,有的团队用 SIP,有的用 XMPP,有的自己写 JSON 协议。WebRTC 要是把信令也标准化了,反而限制了灵活性。
信令负责什么?说白了就三件事:
- 交换 SDP:告诉对方「我支持什么编码、我的 IP 是什么」
- 交换 ICE 候选:告诉对方「我有哪些可能的连接路径」
- 控制会话:谁发起、谁挂断、要不要静音
媒体流负责什么?就是真正的音视频数据。走的是 SRTP/SCTP 协议,加密传输。
我的建议:信令服务器用 WebSocket 实现最简单。别用 HTTP 轮询,延迟太高。我曾经见过一个项目用 HTTP 长轮询做信令,结果信令延迟比媒体流还大,通话建立要 5 秒以上。
2.3 NAT 穿透与 ICE 框架:最难啃的骨头
NAT 穿透,这是 WebRTC 里最让我头疼的部分。你想想,全世界有几十种 NAT 设备,每种的行为都不一样。有的 NAT 会随机分配端口,有的会限制外部连接,有的还会检测协议类型。
ICE 框架就是用来解决这个问题的。它整合了三种技术:
| 技术 | 原理 | 成功率 | 我的经验 |
|---|---|---|---|
| STUN | 问服务器「我的公网 IP 和端口是多少」 | 约 70% | 大部分家用路由器都能过 |
| TURN | 通过服务器中继数据 | 接近 100% | 带宽成本高,慎用 |
| mDNS | 局域网内直接发现 | 局域网内 100% | 适合同 WiFi 场景 |
ICE 的工作流程是这样的:
- 收集所有可能的候选地址(本地 IP、公网 IP、TURN 地址)
- 按优先级排序(P2P 优先,TURN 兜底)
- 双方交换候选列表
- 尝试连接,直到成功
避坑指南:我曾经在部署时忘了开 TURN 服务器的 3478 端口,结果所有用户都连不上。排查了整整一天才发现是防火墙的问题。记住,STUN 和 TURN 的端口一定要在防火墙里放行。
下面这张图展示了 ICE 框架的完整流程:
2.4 SDP 协商机制:双方「握手」的协议
SDP 全称是 Session Description Protocol,翻译过来就是「会话描述协议」。它不负责传输数据,只负责描述「这次通话要用什么参数」。我习惯把它理解成「通话前的体检报告」。
SDP 里包含哪些信息?我列几个关键的:
- 媒体类型:音频、视频、还是数据通道
- 编解码器:H.264、VP8、Opus 等
- 网络信息:IP 地址、端口号
- 传输协议:RTP、SRTP、UDP、TCP
- 带宽限制:最大码率、分辨率
SDP 协商的过程,说白了就是「Offer/Answer」模型:
- 发起方(Offerer)生成一个 SDP,描述自己支持的参数
- 通过信令通道发给接收方(Answerer)
- 接收方解析 SDP,匹配双方都支持的参数
- 接收方生成 Answer SDP,发回给发起方
- 双方确认后,开始传输媒体流
关键点:SDP 协商必须在媒体流传输之前完成。如果协商失败,通话就建立不起来。我见过一个坑——双方都只支持 H.265,但 WebRTC 默认只支持 H.264 和 VP8,结果协商失败。后来加了 H.264 支持才解决。
下面是一个简化的 SDP 示例:
v=0
o=- 123456 2 IN IP4 192.168.1.100
s=-
t=0 0
m=audio 49170 RTP/AVP 0 8 97
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 opus/48000
m=video 49172 RTP/AVP 96 98
a=rtpmap:96 H264/90000
a=rtpmap:98 VP8/90000
a=fmtp:96 packetization-mode=1
这段 SDP 的意思是:音频支持 PCMU、PCMA 和 Opus,视频支持 H.264 和 VP8。接收方会从中选一个双方都支持的编解码器。
我的经验:调试 SDP 问题的时候,最有效的方法就是打印出完整的 SDP 字符串,逐行对比。我曾经花了两天时间,最后发现是 H.264 的 packetization-mode 参数不匹配导致的。记住,SDP 里每一行都很重要。
2.5 小结
WebRTC 的核心架构,说白了就是一套「让浏览器直接通话」的工程方案。P2P 模型省带宽,信令与媒体分离保灵活,ICE 框架搞定 NAT 穿透,SDP 协商确保双方能对上话。这四个部分缺一不可。
实际开发中,我建议你先把 ICE 和 SDP 的流程跑通,再考虑优化。很多新手一上来就折腾编解码器参数,结果连最基本的 P2P 连接都建立不起来。嗯,先把基础打牢,后面的事就好办了。
公众号:蓝海资料掘金营,微信deep3321