WebSocket仅负责WebRTC的信令交换(SDP和ICE候选地址),不参与音视频传输;实际P2P媒体流由RTCPeerConnection通过UDP/TCP直连完成,需配合STUN/TURN服务保障连接可靠性。

WebSocket 本身不参与 WebRTC 的 P2P 数据传输,它只负责信令交换——也就是帮两个浏览器“约好怎么连”,真正音视频流的传输仍由 WebRTC 的 RTCPeerConnection 完成,走的是 UDP(或 TCP fallback)直连通道。所谓“结合”,本质是分工协作:WebSocket 传文字(SDP、ICE candidate),WebRTC 传音视频(二进制流)。
下面分三块讲清楚关键点:
WebSocket 负责传递连接协商信息
WebRTC 无法自己发现对方 IP 和端口,也不懂对方支持什么编解码、用什么加密密钥。这些都得靠你手动传——而 WebSocket 就是最常用、低延迟、全双工的信令通道。
你需要通过它交换两类核心数据:
- SDP Offer / Answer:描述本端媒体能力(如 H.264 编码、opus 音频)、DTLS 证书指纹、传输偏好等;
- ICE Candidate:本端探测到的可能连接地址(如局域网 IP、公网 STUN 地址、TURN 中继地址),每发现一个就发一条给对方。
示例逻辑:A 端创建 Offer → 通过 WebSocket 发给 B → B 收到后 setRemoteDescription,生成 Answer → 再发回 A → 双方各自 addIceCandidate 接收对方候选地址 → 连接建立。
WebRTC 实际完成 P2P 音视频传输
一旦信令完成、ICE 连接成功(connectionState === 'connected'),所有音视频数据就绕过 WebSocket,直接在两浏览器之间流动:
立即学习“Java免费学习笔记(深入)”;
-
getUserMedia()获取本地摄像头/麦克风流; -
addTrack()或addStream()把流塞进RTCPeerConnection; - 对方通过
ontrack事件拿到远端流,绑定到<video>元素即可播放; - 整个过程不经过你的服务器(除非 NAT 穿透失败,需 TURN 中继)。
注意:P2P 是否真正成立,取决于网络环境。同一局域网通常直连;跨运营商或对称 NAT 下,很可能 fallback 到 TURN 中继——这时数据虽经服务器转发,但仍是 WebRTC 协议栈控制,WebSocket 依然只管传信令,不碰媒体流。
必须配齐 STUN/TURN 服务才能落地
光靠 WebSocket + RTCPeerConnection 写出来代码能跑,但大概率连不上。真实场景中必须提供:
- 至少一个公共 STUN 服务器(如
stun:stun.l.google.com:19302),用于获取公网 IP 和端口; - 一个自建或托管的 TURN 服务器(如 Coturn),当双方都在严苛 NAT 后时兜底中继;
- 这些地址要写进
RTCPeerConnection的configuration.iceServers,和 WebSocket 完全无关,但缺它 P2P 就不可靠。
配置示例:
const config = {
iceServers: [
{ urls: "stun:stun.l.google.com:19302" },
{
urls: "turn:your-turn-server.com:3478",
username: "user",
credential: "pass"
}
]
};
const pc = new RTCPeerConnection(config);本质上,WebSocket 是“红娘”,WebRTC 是“新人”,STUN/TURN 是“婚庆场地+备用礼堂”。红娘不办婚礼,只牵线;婚礼现场(音视频)全由新人自己完成。


















