用户间数据传输出选择 WebRTC;用户与服务器之间选择 WebSocket;需存储、搜索、审核的消息属于 WebSocket;服务器权威的多人游戏同样适用 WebSocket。
简而言之:如果数据在用户之间传输,用 WebRTC。如果数据在用户和服务器之间传输,用 WebSocket。
这已经能覆盖大部分场景了。进一步的细化是:"在用户之间"不仅仅关乎地理位置,还关乎数据所有权:一旦你的服务器需要查看、授权、排序或保存这些数据,即使接收方是另一个人,也应该放在 WebSocket 上。
大多数应用程序同时包含这两种流量。所以"二选一"通常是个错误的框架。

TL;DR:WebSocket 是通往服务器的管道。简单、可靠,当服务器拥有状态时是正确的选择。WebRTC 是一整套实时通信栈,优先选择端点之间的直接路径,当找不到可用路由时回退到 TURN 中继。你需要为此付出信令、ICE 协商和中继容量的成本,换来的是真正的媒体处理、可配置的传输方式,以及大部分绕过你基础设施的流量。计划大约五分之一的连接需要中继。
它们真的是可替代的吗?
并不是。它们做的是不同的工作。
WebSocket 将客户端连接到你的服务器。一条长存的 TCP 连接,任何一方可以随时发送数据,每个字节都经过你运行或付费的基础设施。
WebRTC 将两个端点连接在一起。它协商网络路径,加密所有内容,在条件变化时自适应处理媒体,并通过 ICE 找到可行路由时直接发送流量。当找不到时,由 TURN 服务器转发。
所以不要从协议开始。先弄清楚数据需要去哪里,再问你的服务器是否必须参与其中。

这就是为什么真实的应用程序通常两者都会用到。视频通话应用通过 WebRTC 传输媒体,同时通过 WebSocket 处理存在状态、权限和房间状态。协作文档编辑器可能会通过数据通道传输光标位置,同时将实际的文档操作发送到服务器,因为那些操作需要被排序和存储。
四个问题帮你做决定
你的服务器需要检查、授权、持久化、审核或协调这些数据吗?如果是,WebSocket。这一条通常就能单独决定。
经过服务器的多一跳真的有影响吗?延迟和带宽在这里都很重要。
更新可以被丢弃吗?数据通道可以故意设计为无序和不可靠的。WebSocket 是有序的,始终如此。
有多少个端点?两个很简单。超过几个之后,网格拓扑就不工作了,你需要不同的拓扑结构。
值得避免的错误
习惯性地默认选择 WebSocket,然后用它来处理本来就不需要发送到服务器的数据。
这是个容易养成的习惯。WebSocket 更简单,每个教程都从它开始,而且马上就能工作。所以光标位置和瞬态玩家状态会被路由到数据中心再返回,没人注意到问题,因为在四个人同时在线时运行良好。
反过来错也是真实存在的,而且修复代价更高。把服务器拥有的状态推到点对点通道上,只因为接收方恰好是另一个用户。需审核的聊天、权威的游戏状态、任何需要冲突解决的东西——这些都需要服务器在路径中,即使另一端是个人。目的地缩小了选择范围,所有权最终决定选择。
数据通道实际上能给你什么
大多数人都知道 WebRTC 可以处理视频。知道它可以传输任意数据的人较少,而这半部分往往更有用。
数据通道在端点之间移动字节。当 ICE 找到直接路由时,该载荷永远不会到达你的服务器,也不需要支付穿过数据中心的费用。当找不到时,相同的通道会通过 TURN 运行,那部分流量确实会消耗你的中继带宽。
你还获得了一个 WebSocket API 完全不提供的控制能力。通道可以故意设计为不可靠和无序的:
const channel = pc.createDataChannel('game-state', {
ordered: false, // out of order delivery rather than waiting
maxRetransmits: 0 // don't retry — next update supersedes this one
});
这正是光标场景所需要的。200 毫秒前的更新在新数据到达的瞬间就毫无价值了,所以重传它比丢弃它更糟糕。
通过 WebSocket 你没有这个选择。TCP 按序交付,所以一个丢失的数据包会阻塞它后面的所有数据,直到网络自行恢复,而且你的服务器会在两个方向上转发每个字节。
对于文件,保持通道可靠和有序。在做的时候把分块和背压纳入预算。数据通道改变的是字节经过的路由,不是你对流量控制的需求。

如果我选择 WebRTC,需要承诺什么?
比选择 WebSocket 要承担更多。以下是完整的清单。
它不能独立启动
在交换会话描述(SDP)和网络候选者(ICE)之前,两个对等端无法交换任何内容。这个交换必须通过某个已经可用的东西来传输。
这个东西就是信令,而 WebRTC 有意不告诉你如何构建它。WebSocket 是常见选择,因为它支持双向通信,而且你可能本来就想要一个用于状态感知。HTTP 也可以。SIP 也可以。要求是有一个信令服务,而不是 specifically 一个 WebSocket 服务。
信令只是建立连接。一旦 ICE 选择了候选对,媒体和数据通道流量就沿着那条路径传输,并与信令脱钩。
我们在《WebRTC 信令服务器:它是如何工作的》中详细介绍了握手过程,MDN 的指南涵盖了为什么传输层留给你自己决定。
有些连接无法直连
一部分用户根本无法获得直接路径,他们的流量必须通过 TURN 中继。两份生产环境数据集把这个比例定在大约五分之一:

两者都很旧了,而且都不是你的数字。中继率随着用户地理位置、设备、有多少人位于企业防火墙或移动运营商之后,以及你把 ICE 服务器放在哪里而变化。把五分之一作为计划中的数量级,然后一旦进入生产环境就测量你自己的选定候选类型。
其背后的机制值得了解,因为它解释了这个数字为什么会波动。
大多数家用路由器保持公网映射足够长的时间,让两个对等端通过 STUN 找到彼此并连接。有些网络不行。对称 NAT——更精确地说叫端点相关映射——为每个目的地分配不同的公网映射,所以对等端通过 STUN 了解到的关于自身的地址,不是任何其他人可以访问它的地址。运营商级 NAT 做类似的事情。完全阻止 UDP 的防火墙移除了剩余的候选类型。
当 ICE 用尽可用的候选对时,TURN 就是剩下的选择。
这就是为什么企业用户或移动用户占比高的 audience 中,中继比例更高。appear.in 的数据中有一个细节显示了这一点:样本中 78% 的中继通话是通过 TURN/TCP 而不是 UDP 进行的。限制性网络承担了大部分工作。
在实践中:在第一天就架设好 TURN,并在发布前在真正恶劣的网络环境下测试。没有它那些没有直接路径的用户会得到一个协商完成、报告已连接、却什么都传不了的连接。
WebRTC 真的更快吗?
对于两个用户之间的流量,是的,而且有两个原因叠加。
一跳而不是两跳。从 A 到 B 的 WebSocket 消息要上行到服务器再下行。直接数据通道则直接穿过。经由弗吉尼亚的悉尼到悉尼是真实的惩罚,很多应用正在支付这笔费用而不自知。
为实时设计的传输方式。WebRTC 优先使用 UDP,其媒体栈设计为在抖动和丢包时继续播放,而不是停下来等待。TCP 做的是相反的事情:它会持有后面的数据直到缺失的数据包到达。这对文件是正确的,对已经过期的音频帧是错误的。
诚实的警告:被中继的 WebRTC 连接会归还部分跳数优势,因为流量毕竟要经过服务器。它无论无何都保留了媒体处理优势。
对于客户端到服务器的流量,WebRTC 不会缩短任何东西。数据反正都得到达你的服务器。

我能先用 WebSocket 后面再切换吗?
可以,很多团队都应该这样做。WebSocket 中继快速搭建,让你在处理 ICE 状态机之前先验证是否有人需要这个产品。
只是要清醒地认识到,切换不是传输层的替换。你将在已经拥有用户的系统上增加信令、连接状态处理、ICE 协商和中继容量。
有两件事能让这个迁移成本低得多,而且它们今天几乎不花什么代价:
保持负载与传输层解耦。如果应用代码调用的是 send(message) 而不是直接操作 socket,那么替换底层实现的影响就被隔离了。
按归属方而非类型分类流量。你的服务器实际需要关注哪些消息?其余的都是日后迁移到数据通道的候选。尽早做这个分类就是大部分的工作。
如果你已知需要实时媒体或重度点对点数据,直接从 WebRTC 入手。两种方案工作量相当,而且它在有生产流量之前体积更小。
语音智能体让很多团队同时面临这个选择,因为主要平台都支持两种传输方式并让你选择。
OpenAI Realtime API 提供 WebRTC 和 WebSocket 两种连接方式,OpenAI 的官方指导建议浏览器和移动端客户端使用 WebRTC 以获得更稳定的性能。Pipecat 同时提供 WebRTC 和 WebSocket 传输层。
这里有一个结构性差异改变了计算方式。语音智能体通常不是用户对用户的——浏览器在和云端的模型通信,所以有一端是服务器。
这意味着连接问题发生了变化。如果你将 WebRTC 终结在自己运行的基础设施上,要充分测试企业网络和移动网络,并确保有 TURN 路径可用。如果你使用的是托管的 Realtime API,要了解提供商处理了哪些事务,不要假设它和浏览器对浏览器的通话行为一致。我们在《TURN for AI Voice Agents》中讨论过自托管的情况。
对于浏览器端的语音体验,从 WebRTC 入手。把 WebSocket 留给服务器对服务器的集成和控制事件,在那些场景下有序交付比实时媒体行为更重要。

如果你自建 WebRTC,它附带两个服务。两个都很容易在原型阶段被跳过,因为在友好的网络下所有连接都能建立,什么都不会出错。
信令服务。 通常是一个承载 SDP 和 ICE 候选者、房间和在线状态的 WebSocket 服务。快速原型很简单,一旦需要认证、重连、排序和扩展就相当困难了。我们曾在《WebSocket Server: How to Build One》中从零构建过一个。
TURN 中继。 用于 ICE 无法找到直接路径的会话,也就是上面说的五分之一情况。

Open Relay 每月提供 20 GB 免费 TURN 流量。足够用来开发、在刻意测试回退路径,以及运行一个小型产品而无需付费。
Metered TURN 是生产级服务。覆盖 31+ 个区域和 100+ 个边缘接入点,所以中继位于用户附近而非数据中心附近。它在 80 和 443 端口监听,通过 TLS 的 TURNS 协议通信——这正是让你穿透那些产生大部分中继流量的企业防火墙的关键部分。凭证来自 REST API,每次会话获得自己的短期凭证,永久密钥永不进入浏览器。
Metered Realtime 处理信令:SDP 和 ICE 交换、在线状态、发布/订阅。免费使用,每月 100 个并发连接和 100,000 条消息。Open Relay 凭证在客户端连接时注入,所以信令和 TURN 已经预先对接好,而不是作为一个集成项目来处理。
客户端是 @metered-ca/realtime——MIT 许可且开源,除 JavaScript SDK 外还有 Python 和 Flutter SDK。向房间或某个对端发送数据就是它的全部功能:
import { MeteredPeer } from '@metered-ca/realtime';
const peer = new MeteredPeer({ apiKey: PUBLISHABLE_KEY });
await peer.join('room-id');
peer.on('data', ({ senderPeerId, data }) => {
render(senderPeerId, data);
});
await peer.send({ type: 'cursor', x: 420, y: 96 });
// 或者发送给某个对端:
await peer.sendTo(otherPeerId, { type: 'cursor', x: 420, y: 96 });
不需要编写信令服务器,不需要组装 ICE 配置,需要中继的用户已经有了现成的 relay。

我应该用 WebSocket 还是 WebRTC?
当数据在用户之间传输且受益于直接实时路径时用 WebRTC。当你的服务器是数据来源,或者必须进行授权、排序、存储或审核时用 WebSocket。大多数应用两种类型都有,所以两种都会用到。
WebRTC 比 WebSocket 更快吗?
在两个用户之间,通常是的。直接路径是一跳而非两跳,且 UDP 不会因为等待重传而阻塞实时媒体。 relayed 连接会牺牲部分跳数优势,但保留了媒体处理能力。对于客户端对服务器流量没有优势,因为数据反正都要到达你的服务器。
没有服务器能用 WebRTC 吗?
不能。你需要一个信令机制来交换连接详情,以及在 ICE 无法找到直接配对的网络中使用 TURN。"点对点"描述的是媒体最终流向的位置,而不是完全不需要基础设施。
用了 WebRTC 还需要 WebSocket 吗?
通常需要,但不是因为 WebRTC 要求这样做。信令传输是你自己选择的;WebSocket 受欢迎是因为它双向且同时充当你的在线状态通道。HTTP 或 SIP 也可以。
什么时候应该用数据通道而不是 WebSocket?
对于你的服务器不需要关注的用户间流量:光标、临时游戏状态、直接文件传输。你得到一条直接路径和无序交付的选项。如果服务器必须验证、存储、审核或协调这些数据,就用 WebSocket。
无法建立点对点连接的用户会怎样?
配置了 TURN 后,ICE 会选择一个 relayed 候选者,他们正常连接。没有配置的话,连接看起来建立了但没有媒体传输,从工单去诊断这种情况非常痛苦。Open Relay 每月 20 GB 免费流量覆盖了这个场景。
AI 语音智能体应该用 WebSocket 还是 WebRTC?
浏览器和移动端客户端用 WebRTC——这是 OpenAI 对 Realtime API 自己的建议。WebSocket 继续适用于服务器对服务器的集成和控制事件。如果你自建 WebRTC 端点,要测试限制性网络并根据实际观察量估算 TURN 规模。
问自己谁拥有这些数据以及它需要怎样的交付方式。而不是在抽象层面比较哪个协议更好。
在你的用户之间,WebRTC。而且数据通道是那个最常被跳过、让一个本来不需要在路径中的 WebSocket 替代的部分。在用户和你的服务器之间,WebSocket,没有需要重新考虑的。
如果你在运行 WebRTC,要把它依赖的两样东西纳入预算:信令的地方,和五分之一的连接无法直接传输时需要的中继。Open Relay 每月 20 GB 免费 TURN 和 Metered Realtime 的免费信令能让你同时得到这两样,然后点对点路径才能真正触达所有人。
Sources: Philipp Hancke, "What kind of TURN server is being used?" (appear.in rtcstats, 10M calls, Aug 2017) · Lumiaho & Singh, "The Big Churn" (callstats.io, Jan 2015–Feb 2016) · MDN: WebRTC connectivity · MDN: Signaling and video calling · OpenAI: Realtime API with WebRTC · Pipecat SmallWebRTCTransport docs