从此

Web 高级技术 - WebTransport

Web 高级技术


常用、易忘



WebTransport

场景:
  游戏玩家坐标、对内语音等 - 通过数据报(Datagrams)无连接(Connectionless)的覆盖数据;有时候为了防止作弊,只发送按键状态,让服务端来计算最终位置。

概念:
  字节流(Streams)负责可靠传输、数据报(Datagrams)负责非连接型传输,前者需要像 TCP 那样处理粘包、拆包,后者则天生有边界,无需魔数(Magic Number)和长度前缀,前者检查数据头是否存在魔数,但不进行帧同步,直接重连。
  帧同步搜寻(Frame Sync Hunting) - 由于串口信号会被干扰,且不便于断开重连,故需要魔数定界,抛弃魔数前数据,同时尾部还应添加 CRC / Checksum 校验,毕竟没有 TCP 内置的完整性校验。
  单片机因计算资源紧张,故用 CRC 校验,而 PC 可通过 ChaCha20-Poly1305 加解密原文来保证完整性。
  Netty 对于魔数错位的标准做法,是用 LengthFieldBasedFrameDecoder 进行切包,一旦发现魔数对不上,就直接 ctx.close() 重连;发送时添加长度至包头用 LengthFieldPrepender。
  
流程:
  首先进行 QUIC TLS 握手(Handshake),校验后 Client 侧会请求一条可靠的 QUIC“单向控制流”(Control Streams),交换 HTTP/3 SETTINGS 帧(SETTINGS_ENABLE_WEBTRANSPORT = 1、SETTINGS_H3_DATAGRAM = 1),之后客户端请求一条新的 QUIC 双向流,发送 :protocol: webtransport 头的 HTTP/3 CONNECT 请求,服务端响应 200 OK 即连接成功。

Client:
  JS:
    获取 MTU 最大字节 - _WebTransport.datagrams.maxDatagramSize 或写死安全范围内的 1200 字节。
    用 https://github.com/msgpack/msgpack-javascript 库序列化 JS 对象,通过可靠字节流方式传递给 WebTransport Server 端。
  C#:
    序列化库 

Server:
  Java - org.msgpack:msgpack-core 序列化库。

其他

IPv6 规定中间路由器不再负责分片,如果一个大 UDP 包遇到了一个 MTU 较小的路由器,这个包会被直接丢弃,并返回一个 ICMPv6 "Packet Too Big" 消息。