你以为数据只能靠 TCP 可靠传输?今天 WebTransport 用不可靠数据报把这件事彻底原生化了

做过实时协作应用的人都知道,有些数据根本不需要对方确认收到了——光标位置、游戏状态、传感器读数,丢了就丢了,下一秒的新数据会把旧的自然覆盖掉。但 WebSocket 和所有基于 TCP 的方案,都是为「每条消息都必须收到」设计的。这个矛盾今天被 WebTransport 的 datagrams 从根上解了。

什么是 datagrams

WebTransport 和 WebSocket 最根本的区别,不在于底层用 HTTP/3 还是 TCP,而在于同一连接里同时跑着两种性质完全不同的通道:

Streams(可靠流):和 WebSocket 一样,保证顺序、保证到达、丢了会重传。控制指令、聊天消息、关键状态用这个。

Datagrams(不可靠数据报):底层走 QUIC 的 datagram 机制,写进去的数据直接发出去,不等 ACK,不重传,不排队。用 transport.datagrams.writable.getWriter() 取到 writer,直接 writer.write(Uint8Array) 就能发。

两条通道共用同一个握手、同一个 TLS 连接,零额外延迟。

为什么「不可靠」反而是优势

你可能觉得这不对劲——丢了不重传有什么用?

想象你在做一款多人游戏,每个tick要把自己当前坐标发给所有对手。用可靠通道的话:发出去 → 等 ACK → 没收到就重传 → 网络慢的时候整个状态更新卡在队列里。但你要的其实只是「对方知道我现在在哪」,旧的坐标收到也没用,下一秒就更新了。

datagrams 就是为这种场景设计的。发了就忘,QUIC 直接把数据塞进 UDP 包发出去,不等对方回应。新数据覆盖旧数据,丢了无所谓——下一 tick 马上补上。

典型场景:

  • 多人游戏:每帧坐标、旋转角、武器状态,高频且强时序性,丢了旧的新的马上到
  • 协作白板:光标轨迹、选区高亮,不需要可靠,只需要快
  • 实时音视频控制:RTP 的替代品,发指令不需要等待上一个确认
  • IoT 传感器:温湿度、GPS 等读数,每秒十几条,丢一条无感知

一个坑:和 WebSocket 的「回退」不是同一个东西

这里最容易踩的坑,是把 datagrams 等同于 WebSocket。WebSocket 发出去的消息,TCP 层会无限重传直到对方确认收到。你发「左转」,网络抖动时它会等、会影响后续所有消息的顺序。

datagrams 彻底绕开了这个机制。发了就是发了,QUIC 不保证送达,也不在乎顺序。开发者必须自己判断:这条数据,是「必须到」还是「到不了就算了」?

怎么结合两种通道

实战里,两个通道不是二选一,而是组合用。

拿游戏来说:

  • 控制指令(加入房间、切换武器、暂停) → streams,因为丢了必须重发
  • 游戏状态(坐标、HP、子弹) → datagrams,因为每 tick 都会刷新

这样设计出来的实时系统,延迟比纯 WebSocket 低得多,同时关键操作不会因为丢包而出错。

浏览器支持情况

WebTransport 在 Chrome/Firefox 早就有了,但 Safari 一直是缺口。Safari 15.4 勉强支持 streams,但 datagrams 要到 Safari 26.4 才真正能用。随着 Safari 26.4 在 2026 年 3 月稳定版发布,WebTransport 正式达到 Baseline——现在 Chrome、Firefox、Safari、Edge 全部支持,不需要 polyfill。

Firefox 155 还在 datagrams 基础上新增了 send groups,可以给同一连接下的不同流分配带宽优先级,让视频流和游戏状态流不抢带宽。这个我们在 9 月 11 日单独写过一篇,本文重点讲 datagrams 的不可靠机制。

三个生产级注意事项

1. 始终准备 WebSocket fallback

UDP/QUIC 在某些企业网络里会被代理或防火墙拦截。WebTransport 握手失败时自动降级到 WebSocket,是生产部署的标准做法。

2. 单包大小不能超过 MTU

QUIC datagrams 每条消息受 MTU 限制,大约 1200 字节。超出这个大小的数据建议走 streams,datagrams 不做分片。

3. 自己处理丢包检测

没有 ACK 意味着没有自动检测机制。想知道自己发的数据到没到,需要在上层设计心跳或者序列号,自己判断多久没收到就算丢。

下一步

如果你现在在做任何「实时」相关的功能,先问自己:这条数据,丢了重发有意义吗?

如果答案是「没意义,新的会覆盖」,直接用 datagrams。如果答案是「必须到」,用 streams。如果两个都要,WebTransport 两者都给你。

Chrome DevTools Network 面板已经支持看 QUIC 包级别的事件,加载 chrome://net-export/ 可以抓完整日志。

评论区

0 条评论

登录后可评论。