1. WebRTC 全景概览:它到底是什么?
WebRTC,全称 Web Real-Time Communication。说白了,就是让浏览器之间能直接通话、传文件、共享屏幕的一套标准。不需要装插件,不需要第三方软件,打开网页就能用。
我记得 2017 年第一次接触这个技术时,心里还挺震撼的。以前做 VoIP 要用 SIP 协议栈、要处理 NAT 穿透、要自己写音视频编解码……WebRTC 把这些全封装好了。你调几个 API,就能跑起一个实时通话。
1.1 为什么低延迟这么重要?
实时通话,延迟就是生命线。你想想看,两个人打电话,你说完一句话,对方 3 秒后才听到。这种体验,没人能接受。
我做过一个在线教育项目,客户反馈说“老师说话和学生听到之间总有半秒延迟”。半秒!在实时互动里已经非常明显了。后来排查发现是音频缓冲区设得太大,调整后延迟降到了 120ms,体验立刻不一样了。
业内公认的标准是这样的:
| 延迟范围 | 用户体验 | 适用场景 |
|---|---|---|
| 0 - 150ms | 优秀,几乎无感知 | 实时通话、在线教学 |
| 150 - 300ms | 可接受,略有延迟感 | 视频会议、远程协作 |
| 300 - 500ms | 明显延迟,影响交流 | 直播互动(勉强可用) |
| 500ms 以上 | 无法正常对话 | 不适合实时场景 |
WebRTC 的设计目标,就是把端到端延迟控制在 200ms 以内。为了实现这个目标,它用了 UDP 而不是 TCP,用了自适应抖动缓冲,用了 FEC(前向纠错)……这些后面章节会细讲。
1.2 三大核心 API,你必须掌握
WebRTC 的 API 其实不多,但每个都很关键。我按使用频率排个序:
1.2.1 getUserMedia — 获取音视频流
这是最基础的 API。你要通话,总得先拿到摄像头和麦克风的数据吧?
// 获取摄像头和麦克风
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
// 把视频流挂到页面上
const video = document.getElementById('localVideo');
video.srcObject = stream;
这里有个坑,我踩过好几次。getUserMedia 必须在 HTTPS 或 localhost 下才能调用。你如果在 HTTP 页面里调,浏览器直接拒绝。曾经有个同事调试了半天,最后发现是协议问题……
1.2.2 RTCPeerConnection — 建立点对点连接
这才是 WebRTC 的核心。它负责把两端的音视频流传过去,还要处理网络穿透、编解码协商、带宽自适应……
const pc = new RTCPeerConnection({
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' }
]
});
// 把本地流添加到连接
stream.getTracks().forEach(track => {
pc.addTrack(track, stream);
});
// 监听远端流
pc.ontrack = (event) => {
const remoteVideo = document.getElementById('remoteVideo');
remoteVideo.srcObject = event.streams[0];
};
我个人习惯把 RTCPeerConnection 的配置单独抽出来,方便调试。特别是 ICE 服务器列表,生产环境至少配两个 STUN 和一个 TURN,不然 NAT 穿透会出问题。
1.2.3 RTCDataChannel — 传输任意数据
很多人以为 WebRTC 只能传音视频。其实它还能传任意二进制数据,比如文件、文本、游戏状态同步。
// 创建数据通道
const dc = pc.createDataChannel('chat', {
ordered: false, // 允许乱序到达
maxRetransmits: 0 // 不重传
});
dc.onopen = () => {
dc.send('Hello from peer!');
};
dc.onmessage = (event) => {
console.log('收到消息:', event.data);
};
这里有个技巧:如果你传的是实时游戏指令,把 ordered 设为 false,maxRetransmits 设为 0。这样延迟最低,丢包就丢包,不等待重传。如果是传文件,那就用 ordered: true,保证数据完整。
1.3 整体架构长什么样?
我把 WebRTC 的核心流程画了张图,你看一眼就明白了:
流程其实不复杂:
- 获取媒体流 — 用 getUserMedia 拿到摄像头和麦克风数据
- 建立连接 — 通过信令通道交换 SDP 和 ICE Candidate
- 传输数据 — 音视频走 UDP,数据通道走 SCTP
- 接收渲染 — 远端流解码后挂到 video/audio 标签上
1.4 本章小结
WebRTC 不是什么黑魔法。它就是一套标准化的实时通信 API。三个核心接口各司其职:getUserMedia 负责采集,RTCPeerConnection 负责传输,RTCDataChannel 负责数据。
低延迟是 WebRTC 的灵魂。200ms 以内是目标,超过 300ms 就要开始排查问题了。后面章节我会带你一步步定位延迟、回声、丢包这些实战问题。
嗯,第一章就到这里。记住这三个 API 的名字和用途,后面全是围绕它们展开的。