WebTransport 指南:流、数据报、HTTP/3 与适用场景
WebTransport 是一个基于 HTTP/3 的浏览器 API,用于客户端和服务器之间的双向通信。它在同一个连接里提供两类传输方式:可靠流和不可靠数据报。
这让它适合低延迟应用,但它不是 WebSocket 或 WebRTC 的万能替代品。判断是否该用 WebTransport,最好从你的应用数据模式开始。
WebTransport 是什么
WebTransport 允许浏览器连接到 HTTP/3 服务器,并通过两种方式交换数据:
- 可靠流:有序字节流,适合必须正确到达的数据。
- 不可靠数据报:尽力而为的消息,适合低延迟优先、允许丢包的数据。
它运行在安全上下文中,实际使用时应按 HTTPS 处理。它还依赖浏览器、服务器、网络路径、CDN 和代理层对 HTTP/3 的支持。
参考文档:
核心模型
可以把 WebTransport 连接理解成一个会话,里面可以承载多个独立通道。
浏览器
WebTransport 会话
可靠流:聊天消息、文件分块、控制命令
可靠流:另一个独立操作
数据报:玩家位置、传感器更新、实时光标
HTTP/3 服务器
关键点是:不同数据可以使用不同传输规则。支付确认不应该像游戏位置更新一样发送;游戏位置更新也不应该被大文件传输堵住。
流与数据报
| 特性 | 流 | 数据报 |
|---|---|---|
| 传输可靠性 | 可靠 | 尽力而为 |
| 顺序 | 单个流内有序 | 不保证顺序 |
| 适合内容 | 文件、命令、聊天、交易 | 游戏状态、遥测、实时光标 |
| 丢包处理 | 传输层负责可靠性 | 应用必须能容忍丢失 |
| 数据形态 | 字节块 | 独立消息 |
正确性重要时用流。最新值比旧值更重要时,用数据报。
WebTransport 与 WebSocket
WebSocket 仍然是很多应用更简单的默认选择。它部署广、代理友好、生态成熟。
WebTransport 更适合这些需求:
- 一个会话里有多个独立流。
- 需要低延迟的不可靠消息。
- 希望减少无关数据流之间的队头阻塞。
- 想使用基于 HTTP/3 的现代客户端-服务器传输。
这些情况继续用 WebSocket:
- 只需要一个可靠、有序的消息流。
- 希望最大化兼容现有基础设施。
- 服务器、CDN 或公司网络不能稳定处理 HTTP/3。
- 希望运维路径尽可能简单。
不要因为 WebTransport 更新就迁移一个已经稳定工作的 WebSocket 应用。只有当你的数据模式真正受益于流、数据报或 HTTP/3 特性时,迁移才有意义。
WebTransport 与 WebRTC Data Channel
WebRTC Data Channel 更偏向点对点或媒体相关实时系统。WebTransport 是客户端到服务器。
适合 WebRTC 的情况:
- 浏览器需要点对点通信。
- 应用本来就包含音视频协商。
- 需要 WebRTC 基础设施处理 NAT 穿透。
适合 WebTransport 的情况:
- 浏览器主要和你的服务器通信,而不是直接和另一个浏览器通信。
- 希望使用更接近 Web 平台的 Streams API。
- 不需要完整 WebRTC 技术栈。
如果你已经有稳定的 WebRTC 架构,WebTransport 未必能带来足够收益来支撑重写。
基础客户端写法
使用前一定要做功能检测。
async function connectWebTransport(url) {
if (!("WebTransport" in globalThis)) {
throw new Error("WebTransport is not available in this browser.");
}
const transport = new WebTransport(url);
transport.closed
.then(() => {
console.log("WebTransport closed normally.");
})
.catch((error) => {
console.error("WebTransport closed unexpectedly:", error);
});
await transport.ready;
return transport;
}
const transport = await connectWebTransport("https://example.com:4433/wt");
生产环境要把这段封装到降级逻辑里。如果 WebTransport 不可用或连接失败,根据功能切换到 WebSocket、Server-Sent Events 或普通 HTTP。
发送数据报
数据报适合频繁状态更新,尤其是旧消息很快失去价值的场景。
const writer = transport.datagrams.writable.getWriter();
const encoder = new TextEncoder();
await writer.write(encoder.encode(JSON.stringify({
type: "cursor",
x: 240,
y: 180,
t: Date.now()
})));
设计数据报时,每条消息都应该能独立理解,不要依赖前面的每一条数据报都被收到。
适合数据报的内容:
- 当前玩家位置。
- 最新光标位置。
- 传感器读数。
- 输入状态或在线心跳。
- 实时预览状态。
不适合数据报的内容:
- 支付操作。
- 账户变更。
- 需要严格顺序的文档编辑。
- 任何必须审计的操作。
使用可靠流
如果接收方必须按顺序拿到所有字节,就用流。
const stream = await transport.createBidirectionalStream();
const writer = stream.writable.getWriter();
const reader = stream.readable.getReader();
const encoder = new TextEncoder();
const decoder = new TextDecoder();
await writer.write(encoder.encode("hello"));
const { value } = await reader.read();
if (value) {
console.log(decoder.decode(value));
}
await writer.close();
互不相关的操作应该放到不同流里。这样大文件传输不会阻塞小的控制消息。
上线前检查清单
上线 WebTransport 前,要检查整条链路:
- 目标用户的浏览器支持情况。
- 服务器是否支持 HTTP/3。
- TLS 证书和安全上下文配置。
- UDP 和 QUIC 在防火墙、公司网络中的表现。
- CDN 或反向代理是否支持。
- 长连接会话下的负载均衡行为。
- 连接失败率、重试率和降级使用率监控。
- 流的背压处理。
- 数据报消息大小限制。
- 会话建立时的认证和授权。
最难的部分往往不是浏览器 API,而是网络和服务器部署。
降级策略
一个实用的降级策略可以是:
优先尝试 WebTransport
如果不可用或连接失败:
用 WebSocket 承接双向可靠消息
如果不需要双向:
用 Server-Sent Events 做服务器推送
如果实时性不是必须:
用 fetch 轮询
即使传输方式变化,产品体验也要保持可预期。例如仪表盘可以在降级后变成较慢的轮询;实时游戏则可能需要禁用对应房间。
适合使用 WebTransport 的场景
当应用同时有可靠数据和低延迟尽力而为数据时,WebTransport 值得评估:
- 多人游戏状态加可靠比赛事件。
- 协同编辑光标加可靠文档操作。
- 高频遥测加可靠控制命令的实时仪表盘。
- 远程设备控制中的状态更新和命令流。
- 需要服务器实时数据通道的媒体相关应用。
共同特征是混合流量:有些数据必须到达,有些数据必须新鲜。
不适合使用的场景
这些情况应避免使用 WebTransport:
- 普通 REST 或 fetch API 已经够用。
- 一个 WebSocket 消息流就能干净解决问题。
- 需要兼容较旧浏览器。
- 部署链路不能稳定支持 HTTP/3。
- 需要浏览器点对点通信。
- 团队不想维护传输层降级逻辑。
新的传输技术只有在解决真实产品痛点时才有价值。
总结
WebTransport 给浏览器应用提供了基于 HTTP/3 的现代客户端-服务器传输,支持可靠流和不可靠数据报。它的价值不是“全面替代 WebSocket”,而是让一个会话能承载不同实时数据,并按不同可靠性要求传输。
如果你的应用真的需要这种灵活性,就配合功能检测、降级方案和生产监控一起上线。
本站提供浏览器本地工具,免注册即可试用 →