@u3d-uos/h5-netcode
v0.8.0
Published
Lightweight state-synchronization networking framework for H5 games
Readme
@u3d-uos/h5-netcode
轻量级 H5 游戏状态同步网络框架。
项目简介
h5-netcode 是一个面向浏览器端(H5)实时多人游戏的网络同步框架,采用经典的 客户端预测 + 服务端校正 + 快照插值 三件套架构,并在此基础上扩展了共享世界模式、增量压缩、可插拔传输层等能力。框架用 TypeScript 编写,类型完全泛型化——输入和状态的形状由开发者自定义,框架不绑定任何具体游戏逻辑。
解决的核心问题
| 问题 | 现象 | 框架方案 | |------|------|----------| | 输入延迟 | 按键后角色 100ms 才移动 | 客户端预测,本地立即响应 | | 状态不一致 | 客户端/服务端位置偏差 | 服务端权威 + 回滚重放校正 | | 网络抖动 | 远端玩家瞬移 | 快照插值 + 自适应抖动缓冲 | | 带宽浪费 | 每 tick 发送完整状态 | 累积增量压缩,丢包自动恢复 | | 断线丢失 | 切后台导致进度丢失 | 会话挂起/恢复 + Token 重连 |
功能特性
同步核心
- 客户端预测 — 本地输入立即应用到状态,输入缓冲支持回滚重放
- 服务端校正 — 通过用户提供的
ReconcileFn比较预测值与权威值,超阈值时回滚并重放未确认输入 - 快照插值 —
SnapshotBuffer缓存服务端快照,在两个快照之间插值实现远端实体平滑渲染 - 增量压缩 — 累积增量快照(自上次全量以来的所有变化),丢包由下一个增量自动恢复
- 自适应抖动缓冲 — 基于 EMA 估算网络抖动,动态调整插值延迟
预测策略
- 回滚策略(Rollback,默认) — 经典回滚+重放,要求
simulate函数确定性 - EMA 策略 — 指数移动平均渐变修正,适用于非确定性引擎(物理引擎浮点误差、动画驱动位移、第三方黑盒引擎)
- 状态感知预测 — 通过
isPredictable回调跳过不可重放状态(如射击/击退/死亡),等待服务端权威状态 - 边缘输入累积 —
accumulateKeys解决高刷新率屏幕(120/144Hz)下 tap 输入(跳跃/射击/冲刺)在渲染帧间被覆盖丢失的问题
共享世界模式
适用于所有玩家共享同一个世界状态的游戏(体育、RTS、合作 PvE、棋盘/卡牌等),由 SharedWorldServerLoop / SharedWorldClientLoop 提供:
- 服务端维护单一
TWorld,由所有玩家输入共同推进 - 客户端仅预测本地玩家,远端世界实体通过插值平滑
- 内置默认世界 diff/patch,支持显式删除、原子数组、不透明路径、量化、节流、字段级策略
- AOI(兴趣区域)世界投影 — 按客户端过滤世界视图,支持投影缓存和可见区域变化时安全重置增量基
- 恰好一次命令通道 — 有序投递、确认、队列背压、去重、重试、重连安全
- 瞬态游戏事件通道 — 作用域内批量可靠/不可靠表现层事件,客户端去重与插值对齐的
playAt时序
传输层
- 可插拔传输 — 统一
ITransport/IServerTransport接口,按需选择 - Socket.IO — TCP 传输,开发友好,
volatile.emit实现不可靠通道 - Geckos.io — WebRTC DataChannel 传输,
raw.emit实现真正的 UDP 不可靠通道 - 通道自动路由 — 每种包类型自动路由到可靠/不可靠通道
- TLS/WSS 支持 — 直接传入证书或通过反向代理终止 TLS
- 客户端/服务端子路径分离 — 浏览器打包不会引入 Node-only 依赖
安全与可靠性
- 协议 v4 — 严格校验版本不匹配、畸形/截断包、未知标志/类型、尾部多余字节
- 认证重连 — 不可猜测的轮换 Token,服务端仅存储哈希,拒绝缺失/无效/重放凭证
- 输入验证与限流 — 声明式
inputSchema清理输入字段,逐客户端输入/命令/字节速率限制(仅SharedWorldServerLoop) - 输入批处理 — 每 tick 每玩家至多一个合并输入,布尔边缘字段 OR 合并
- 有界缓冲 — 字符串和集合长度使用
uint16编码,客户端输入缓冲有上限
遥测与监控
- 客户端自动统计上下行带宽(
telemetryEnabled: true),无需手动包装BandwidthTracker - 服务端
getMetrics()暴露流量、快照数量、活跃连接数、tick 耗时 p50/p95/p99 - 运行时配置 — 客户端
updateConfig()可在运行时切换预测、校正、插值、抖动缓冲、遥测等开关;增量压缩通过client.config包切换服务端行为
渲染层平滑
EntitySmoother— 指数平滑或临界阻尼平滑,可选速度外推(dead reckoning),有界外推时间,大修正后吸附createInterpolator— 声明式插值器,支持嵌套路径、四元数 slerp、角度插值、吸附字段、跳过字段
不透明二进制载荷
支持将游戏引擎(Unity BitSerializer、Cocos 自定义协议、Protobuf、FlatBuffers 等)产生的原始 Uint8Array 直接嵌入状态,msgpack 原生编码为 bin 类型,零额外开销往返。
架构概览
四层清晰分离的架构:
┌───────────────────────────────────────────┐
│ Client / Server │
│ ClientLoop / ServerLoop │
│ SharedWorldClientLoop / SharedWorldServer│
├───────────────────────────────────────────┤
│ Transport │
│ ITransport / IServerTransport │
├───────────────────────────────────────────┤
│ Shared │
│ Types / Binary Codec / Strategies / Math │
└───────────────────────────────────────────┘- Shared — 唯一被双向依赖的层,定义协议、类型、二进制编解码和工具函数
- Transport — 仅依赖 Shared,提供可插拔的传输实现
- Server / Client — 各自依赖 Transport + Shared,互不依赖。每层提供两种循环:经典模式(
ClientLoop/ServerLoop)和共享世界模式(SharedWorldClientLoop/SharedWorldServerLoop)
安装
npm install @u3d-uos/h5-netcode传输库(socket.io、socket.io-client、@geckos.io/client、@geckos.io/server)为可选 peer 依赖,按需安装:
# Socket.IO 传输
npm install socket.io-client # 客户端
npm install socket.io # 服务端
# Geckos.io (WebRTC) 传输
npm install @geckos.io/client # 客户端
npm install @geckos.io/server # 服务端模块入口
| 入口路径 | 说明 |
|----------|------|
| @u3d-uos/h5-netcode | 客户端入口(重新导出 @u3d-uos/h5-netcode/client) |
| @u3d-uos/h5-netcode/client | 预测、校正、快照插值、重连管理、实体平滑 |
| @u3d-uos/h5-netcode/server | 游戏房间管理、服务端 tick 循环、输入验证、限流 |
| @u3d-uos/h5-netcode/shared | 共享类型、二进制工具、数学函数、策略接口 |
| @u3d-uos/h5-netcode/transport | 传输接口、BandwidthTracker、TransportType |
| @u3d-uos/h5-netcode/transport/socketio/client | Socket.IO 客户端传输(浏览器安全,无 Node 依赖) |
| @u3d-uos/h5-netcode/transport/socketio/server | Socket.IO 服务端传输 |
| @u3d-uos/h5-netcode/transport/geckos/client | Geckos.io 客户端传输(浏览器安全,无 Node 依赖) |
| @u3d-uos/h5-netcode/transport/geckos/server | Geckos.io 服务端传输 |
| @u3d-uos/h5-netcode/transport/socketio | Socket.IO 组合入口(同时导出客户端 + 服务端) |
| @u3d-uos/h5-netcode/transport/geckos | Geckos.io 组合入口(同时导出客户端 + 服务端) |
打包提示: 在浏览器/webpack 构建中导入传输层时,请使用
/client或/server子路径,不要使用组合式的@u3d-uos/h5-netcode/transport/socketio或@u3d-uos/h5-netcode/transport/geckos导出——后者会同时引入客户端和服务端类,可能拉入 Node-only 依赖(http、https、node:url)导致浏览器打包失败。
Demo
# Socket.IO 传输(默认)
npm run demo
# Geckos.io 传输
npm run demo:geckos
# 共享世界模式 Demo
npm run demo:world然后打开 http://localhost:5173。
文档
| 文档 | 说明 | |------|------| | Quick Start | 集成清单 + 完整可运行示例(服务端 + 客户端 + 共享世界模式) | | API Reference | 全部类、接口、选项的详细参考 | | Walkthrough | 架构设计与核心概念详解 |
测试
npm test # 运行单元测试
npm run test:install # 运行安装集成测试
npm run test:all # 运行全部测试基准测试
npm run bench:world-diff # 共享世界 diff/patch 基准