Back

使用 WebTransport 实现低延迟浏览器通信

使用 WebTransport 实现低延迟浏览器通信

如果你曾经构建过多人游戏、实时遥测仪表板或实时协作工具,很可能已经触及了 WebSockets 的性能上限。单一有序流在大多数情况下工作良好,但当一个慢速数据包阻塞了后续所有数据时,用户会立即感受到延迟。

WebTransport API 正是为解决这个问题而设计的。它为浏览器提供了一个基于 HTTP/3 的低延迟通信通道,支持可靠流和不可靠数据报——而且不会出现基于 TCP 传输协议固有的队头阻塞问题。

核心要点

  • WebTransport 运行在 QUIC(HTTP/3)之上,消除了基于 TCP 的 WebSockets 固有的队头阻塞问题。
  • 它提供两种通信原语:用于时间敏感数据的不可靠数据报和用于有序传输的可靠流。
  • 多个流在单一连接上独立运行,因此一个流的停滞不会阻塞其他流。
  • WebTransport 并非 WebSockets 的全面替代品——当你的应用需要多路复用、低延迟或混合传输保证时,它才是更好的选择。

WebTransport API 的实际功能

WebTransport 建立与 HTTP/3 服务器的连接,并提供两种不同的通信原语:

  • 数据报(Datagrams) — 不可靠、无序、低开销的数据包。类似 UDP,但内置了加密和拥塞控制。
  • 流(Streams) — 可靠、有序的数据通道。多个流可以在单一连接上并行运行而不会相互阻塞。

与 WebSockets 的关键架构差异在于,WebTransport 运行在 QUIC 之上,这是一种基于 UDP 的传输协议。QUIC 独立处理每个流,因此一个停滞的流不会延迟其他流。而基于 TCP 构建的 WebSockets 没有这种隔离机制——一个慢速消息会阻塞整个连接。

WebTransport 流和数据报:传输语义

在选择使用哪种原语之前,理解传输保证至关重要。

数据报可能会丢失或乱序到达。它们的大小受路径 MTU 限制。当数据的新鲜度比完整性更重要时使用它们——比如游戏输入、传感器读数、光标位置。

保证在给定流内的有序、可靠传输。你可以打开单向流(客户端到服务器或服务器到客户端)或双向流。重要的是,有序性仅在单个流内得到保证,而不是跨多个流。

const transport = new WebTransport("https://example.com:4999/game")
await transport.ready

// 发送低延迟数据报
const writer = transport.datagrams.writable.getWriter()
await writer.write(new Uint8Array([1, 2, 3]))

// 打开可靠的双向流
const stream = await transport.createBidirectionalStream()
const streamWriter = stream.writable.getWriter()
await streamWriter.write(new Uint8Array([4, 5, 6]))

WebTransport 与 WebSockets:何时使用各自

这不是替代关系——而是适配关系。

场景更好的选择
简单聊天或信令WebSockets
高频率游戏状态更新WebTransport 数据报
多个独立数据通道WebTransport 流
需要广泛的浏览器兼容性WebSockets
媒体同步 + 控制通道组合WebTransport(混合模式)

当你需要单一可靠消息流且浏览器兼容性很重要时,WebSockets 仍然是正确的工具。当你的应用真正受益于多路复用或可以容忍部分传输时,WebTransport 才显现其价值。

WebRTC 数据通道提供类似的功能,但需要 ICE 协商、STUN/TURN 服务器以及大量的设置开销。对于客户端-服务器场景,WebTransport 更简单,并且可以在 Web Workers 中工作。

浏览器支持和基础设施要求

WebTransport 需要安全上下文(HTTPS)和支持 HTTP/3 的服务器。它在基于 Chromium 的浏览器(Chrome、Edge)中得到良好支持,Firefox 也已获得支持。Safari 的支持是最近才加入的。它尚未被视为普遍基线,因此特性检测至关重要。当前的支持详情可以在 webstatus.dev 上查看。

if ("WebTransport" in window) {
  // 使用 WebTransport
} else {
  // 降级到 WebSocket
}

对于本地开发,webtransport.day 提供了一个社区维护的回显服务器,你可以在不搭建自己的 HTTP/3 基础设施的情况下进行测试。

结论

WebTransport 不是替代 WebSockets——而是扩展了浏览器的可能性。其真正价值在于架构层面:你现在可以通过单一连接发送不可靠的时间敏感数据以及可靠的控制消息,而且互不影响。对于延迟和吞吐量都很重要的实时应用来说,这是一项值得拥有的重要能力。

常见问题

WebTransport 主要设计为通过 QUIC 运行在 HTTP/3 之上。在当前实践中,部署 WebTransport 通常意味着使用支持该协议的 HTTP/3 服务器。对于本地测试,你可以使用像 webtransport.day 这样的社区回显服务器,或使用 aioquic(Python)或 quiche(Rust)等库搭建本地 QUIC 服务器。

丢失的数据报不会被重传。应用程序永远不会收到它们。这是设计使然。数据报用于最新值比接收每个值更重要的数据,例如玩家位置或实时传感器读数。你的应用逻辑应该优雅地处理丢失的数据包。

可以。一个常见模式是使用 WebTransport 作为主要传输方式,当浏览器或网络不支持 HTTP/3 时降级到 WebSockets。你可以通过简单检查 window 对象中是否存在 WebTransport 构造函数来检测支持情况,并相应地切换传输方式。

对于客户端-服务器使用场景,WebTransport 要简单得多。WebRTC 数据通道是为点对点场景设计的,需要 ICE 协商、STUN 和 TURN 服务器以及复杂的会话设置。WebTransport 只需一个构造函数调用即可直接连接到 HTTP/3 服务器,而且还可以在 Web Workers 中工作。

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay