打开微信视频号刷直播、用Discord和朋友语音开黑、在网页上参加一场视频会议——这些场景里你大概率没用过任何浏览器插件。浏览器凭什么能直接采集摄像头、和千里之外的另一个浏览器实时通话,甚至不走服务器中转?答案就是WebRTC。

WebRTC(Web Real-Time Communication)是W3C和IETF联合制定的开放标准,最早由Google在2011年开源,2021年成为W3C正式标准。如今Chrome、Firefox、Safari、Edge等主流浏览器都已原生支持。Google Meet、Slack、WhatsApp、Discord等主流通信工具都跑在它上面。

传统方案为什么不行?

在WebRTC出现之前,浏览器做实时通信的套路是:用户A的摄像头数据上传到服务器,服务器再转发给用户B。这条路走不通的原因很简单——带宽成本翻倍、延迟必然高、服务器成本爆炸。那个时代的大型直播,基本是专有协议加Flash插件,用户还得手动安装。

WebRTC的出现改变了这一切——点对点通信、端到端加密、无需插件。一句话总结:浏览器之间可以直接说话了

三个核心API,撑起整个WebRTC

WebRTC的本质是一套浏览器JavaScript API的集合,核心目标就三个字:分散流量。最关键的三个API是:

  • getUserMedia():获取摄像头和麦克风的实时数据流
  • RTCPeerConnection:两个浏览器之间的“连接管道”,负责音视频的传输
  • RTCDataChannel:除了音视频,还能传文件、文本消息

WebRTC连接到底是怎么建立的?

表面上看只是打开一个网页、点一下“加入通话”,背后其实走了一套完整的五步流程:

第一步,媒体准备。双方通过getUserMedia()获取本地摄像头和麦克风,把音视频轨道绑定到RTCPeerConnection对象上。

第二步,SDP Offer创建。发起方生成一份SDP(会话描述协议)描述——里面写清楚了“我支持什么编解码器、什么媒体格式、什么网络能力”,然后通过信令通道发给对方。

第三步,SDP Answer创建。接收方收到Offer后,生成自己的SDP Answer回应,同样通过信令通道返回。

第四步,ICE候选地址交换。双方各自收集自己的网络地址和端口组合(称为ICE候选地址),通过信令服务器互相交换。

第五步,直接连接建立。ICE框架在所有候选地址中选出最优路径,DTLS-SRTP握手加密,媒体流直接在两个浏览器之间流动。

信令、STUN、TURN:藏在背后的三个关键角色

WebRTC只管媒体传输,不管“怎么找到对方”这件事。所以还需要三个辅助角色:

信令服务器负责在连接建立前,帮双方交换SDP Offer/Answer和ICE候选地址。用什么协议传输都行——WebSocket、HTTP、XMPP随你选。连接一旦建立,信令服务器的任务就结束了。

STUN服务器负责帮客户端发现自己的公网IP和端口映射。它解决了大约85% 的NAT穿透问题。ICE框架会收集三种候选地址:本机IP、STUN发现的外网IP、TURN中继地址。ICE测试每一对候选地址,第一对成功的就是最终路径。

TURN服务器是最后的保底方案。当STUN失效时——比如对称型NAT、严格的企业防火墙——TURN会中继所有媒体流量。TURN会增加50-80ms延迟,但能保证连通性。跳过TURN意味着大约15%的用户永远连不上

数据通道:不止是音视频

除了音视频,WebRTC的RTCDataChannel还能传输任意数据——文件、文本消息、游戏状态同步都可以。DataChannel底层基于SCTP协议,主流浏览器对MTU有硬性限制:Chrome/Firefox默认64KB,Safari早期版本仅16KB。传输大文件时需要手动分片,比如每16KB一个包,配合流量控制逐包发送。

WebRTC到底能干什么?

WebRTC最擅长的场景是双向实时交互

  • 视频会议:Google Meet、Zoom、Slack都在用
  • 在线教育:双师课堂,音视频延迟从300ms降到150ms以内
  • 远程医疗:会诊系统,实时传输高清影像
  • 直播连麦:抖音、视频号的PK连麦
  • 实时游戏:浏览器里的多人游戏,通过DataChannel同步状态

但如果需要覆盖成千上万的纯观看用户,WebRTC并不适合——这时候应该用WebRTC推流到服务器,再通过HLS分发给大规模观众。

一句话总结

WebRTC不是一个单一协议,而是一整套技术栈的集合——getUserMedia采集音视频,RTCPeerConnection建立P2P连接,SDP协商媒体参数,ICE+STUN/TURN解决NAT穿透,DTLS-SRTP保证端到端加密。它把过去需要几十台服务器、几百行后端代码才能做的事,压缩成了浏览器里几行JavaScript。