Skip to main content

WebTransport 与新一代实时传输

WebTransport 基于 HTTP/3 + QUIC,提供多路独立流与不可靠数据报。它在 2026 年随 Safari 支持进入 Baseline。

一、多路流与不可靠数据报​

WebSocket 提供的是一条有序可靠的字节流,跑在 TCP 上。这个模型有两个先天限制:

  • 队头阻塞 —— TCP 没有「流」的概念,一个包丢了,后面所有数据都得等它重传,即使逻辑上它们属于不同通道;
  • 只有一种可靠模式 —— 要么保证有序到达,要么没有,没有中间选项。

WebTransport 基于 QUIC,正好补上这两块:

  • 多条独立流 —— 一条连接上可以开几十条流,流 A 丢包不会阻塞流 B;
  • 不可靠数据报 —— 允许丢包、允许乱序,适合「最新值比完整历史更重要」的数据(位置同步、遥测、游戏状态);
  • 连接迁移 —— QUIC 用连接 ID 而非 IP 四元组标识连接,Wi-Fi 切到蜂窝网络不会断;
  • 0-RTT 建连 —— 回访客户端可以在第一个往返就带数据。

一个容易被忽略的额外收益:它支持标准的 Authorization 请求头、HttpOnly Cookie 与 CORS。WebSocket 的握手 historically 不支持自定义头,导致大量实现把 token 拼在 URL 查询串里——而那会把令牌明文留在服务器访问日志和浏览器历史里。WebTransport 从机制上避免了这个问题。

WebSocket一条 TCP 字节流一个包丢了,全部消息都得等握手不能带自定义头WebTransport一条 QUIC 连接上多条独立流丢包只影响所在那条流另有独立的数据报通道,不保证到达但要先确认服务端支持:UDP 被封时它是直接连不上,不会自己退回 WebSocket。
图:WebSocket 与 WebTransport 的能力差异——多流与数据报是它的真正增量

二、进入 Baseline 的时间线​

截至 2026 年 10 月:

  • 浏览器端已达成 Baseline —— Chrome 97+、Edge 98+、Firefox 114+,Safari 26.4(2026 年 3 月)补上了最后一块,至此主流引擎全部支持,不需要 flag 或 polyfill。
  • 服务端与基础设施仍在追赶 —— 这是当前的真实短板。Nginx 的 HTTP/3 支持仍是实验性开关而非 GA;很多团队选择把 WebTransport 跑在专门的边缘层(Envoy、支持 QUIC 的边缘平台)上,而不是通用 Web 服务器。

所以现状是:浏览器准备好了,基础设施不一定。 如果你的架构里已经有一个现代边缘层,接入是可控的增量;如果是小型团队跑着一台普通服务器,这就是一笔实打实的基础设施投入。

它的失败方式是异步的——构造不会抛错,得靠 ready 的 reject 捕获:

if (!('WebTransport' in window)) return fallbackToWebSocket()

try {
const wt = new WebTransport(url)
await wt.ready // UDP 被封、证书不对都会在这里 reject
} catch (e) {
return fallbackToWebSocket() // 回退路径必须提前写好,不能只在 happy path 上测
}

三、依赖 HTTP/3 与 UDP​

  • 必须 HTTPS —— 它跑在 HTTP/3 上,而 QUIC 内建 TLS 1.3,没有明文模式;
  • 依赖 UDP 443 可达 —— 企业防火墙、部分代理会封 UDP,连接会直接失败(wt.ready 抛出),不会自动降级到 HTTP/2,应用需要自己回退到 WebSocket;
  • 观测变难 —— 加密的传输头让传统抓包几乎失效,需要结构化日志(qlog 一类)支撑排障;
  • 服务端生态仍在成长 —— 库与中间件的成熟度明显落后于 WebSocket。

四、和 WebRTC 各自的场景​

两者常被放在一起比,但解决的问题不同:

  • WebRTC —— 面向点对点的音视频,自带编解码协商、回声消除、带宽估计;
  • WebTransport —— 面向客户端-服务器的数据交换,给的是可靠性与多路复用的细粒度控制。

需要多人音视频、屏幕共享时选 WebRTC;需要低延迟地向服务端收发数据时用 WebTransport。不是替代关系。

数据报与流是两套语义,选错就享受不到它的优势:

// 不可靠数据报:丢了不重传,适合位置同步、实时状态
const w = wt.datagrams.writable.getWriter()
await w.write(new Uint8Array([1, 2, 3]))

// 可靠流:顺序保证、可单独关闭写端,适合大块数据
const stream = await wt.createBidirectionalStream()
await stream.writable.getWriter().write(chunk)

五、什么时候值得上​

结论要克制:WebSocket 依然是默认答案,它生态成熟、网关友好、实现简单,绝大多数业务场景用不上 WebTransport 的那部分能力。

考虑 WebTransport 的条件是:

  1. 延迟与丢包敏感度极高(云游戏、实时协同、高频遥测);
  2. 确实需要不可靠数据报或多路独立流带来的隔离性;
  3. 已经有 HTTP/3 基础设施,或愿意为此投入。

无论哪种情况,都要先做能力探测,不支持时降级:

async function createChannel(url) {
if (!('WebTransport' in window)) return createWebSocket(url) // 降级
try {
const transport = new WebTransport(url)
await transport.ready
return transport
} catch {
return createWebSocket(url) // 建连失败也要有退路
}
}
// 可靠流与不可靠数据报可以并存
const stream = await transport.createBidirectionalStream()
const writer = stream.writable.getWriter()
writer.write(new TextEncoder().encode('需要保证到达的数据'))

const datagram = transport.datagrams.writable.getWriter()
datagram.write(new TextEncoder().encode('丢了也无所谓的位置更新'))
// 接收对端发来的不可靠数据报:只取最新值,旧数据丢了也无妨
const reader = transport.datagrams.readable.getReader()
while (true) {
const { value, done } = await reader.read()
if (done) break
applyLatestState(new TextDecoder().decode(value)) // 覆盖式更新,不累积历史
}

六、该选哪一个​

浏览器端已经全覆盖,但服务端生态与基础设施仍然落后,短期内 WebSocket 依然是默认选择(截至 2026 年 10 月)。

它也不是 WebRTC 的替代品——一个面向客户端与服务器之间的数据,一个面向点对点媒体,场景不同。

不可靠数据报更不是缺点:对实时性优先的数据(位置、状态广播)它是优点,因为旧数据比丢包更没用。

所有环境都能用同样不成立:它依赖 UDP 443 可达与 HTTP/3 基础设施,被封 UDP 的网络会静默失去收益。

WebSocket 依然是默认答案,WebTransport 是为「延迟极度敏感且已有 HTTP/3 基础设施」的那部分场景准备的。

WebTransport 的接口形态与支持范围见 MDN:WebTransport,这块仍在演进。