Files
Workspace/Docs/NetworkV2Migration.md
T
cneicy 0d9e04c09d
Validate ShrinkSDK Workspace / catalog (push) Successful in 4s
Validate ShrinkSDK Workspace / unity (push) Successful in 3m20s
chore(release): publish supplemental packages and remove internal reports
2026-09-29 10:42:21 +08:00

5.4 KiB
Raw Blame History

Network v2 与诊断接入迁移

网络消息体的编码器与包封装现已分离。所有 ShrinkNetworkService 使用 SHK2 二进制封装;协议版本为 2,旧 JSON/MessagePack 外层包会被拒绝。客户端与服务端必须一起升级。直接使用 TCP/KCP transport 传递自定义字节的项目保留自己的上层协议,不能把其版本号与 ShrinkNetworkService 的协议号混同。

消息编码与所有权

  • JSON 消息编码仍可显式选择 ShrinkJsonNetworkSerializer,不再将字节消息体嵌入 JSON 外层包而产生 Base64。
  • 原反射式 ShrinkMessagePackNetworkSerializer 已移除。安装可选的 ShrinkSDK.Network.MessagePack/UPM 适配包,引用 ShrinkNetwork.MessagePack,传入生成的 resolver,并对每个消息类型调用 Register<T>()。适配器只补充基础类型 formatter,不使用动态泛型反射回退。
  • ShrinkNetworkPacket.Payload 从 byte[] 改为 ReadOnlyMemory<byte>。只有需要独立所有权时调用 ToArray();ShrinkPacketCodec.Decode 借用输入内存。
  • 实现 IShrinkNetworkBufferSerializer 可直接写入 IBufferWriter<byte>。旧消息序列化接口保留兼容路径,但会产生中间数组。
  • 实现 IShrinkNetworkMemoryTransport 时,发送任务完成、取消或失败之前必须保持输入有效;任务结束后不能继续访问。服务层负责在 await 结束后归还池内存。旧传输接口收到独立数组。
  • 广播可先编码消息体并使用 SendSerializedAsync,外层会话信息仍按收件人生成。调用方在所有发送完成前不得修改共享消息体。

排队行为

默认自动派发按序执行处理器;Unity/Godot 的主线程接入可使用 ShrinkNetworkDispatchQueue,按帧调用带数量、字节、时间预算的 PumpAsync。预算不会抢占正在执行的 handler;为避免饥饿,每轮允许首个合法包超过本轮字节预算。

可靠接收队列只允许 Reject。原 DropNewest/DropOldest 配置会明确报错。拒绝通过 OnDispatchRejected 与指标反馈;支持会话控制的 transport 会断开连接,以免继续使用缺失可靠操作的状态。

显式状态合并使用 ShrinkNetworkWorkQueue.EnqueueAsync 的 stateKey,只在相同 session/channel/key 内替换未执行项,替换后的项移至该分区队尾。返回值区分 Completed、Rejected、Replaced、Canceled;异常继续向调用方传播。RPC、可靠业务操作、存档事务和快照分片不能使用普通状态替换。多个分区轮转,但处理器仍串行执行。

RPC 响应单独完成挂起请求,避免嵌套调用等待当前处理队列而死锁。处理器的 async continuation 线程仍取决于其等待对象;访问引擎对象前由宿主保证线程切换。

Context 与存档

ShrinkContextRuntime.Fibers 只保留仍被运行时管理的 fiber。退役历史改为有界纯数据诊断,构造参数 retiredHistoryCapacity 默认 64;需要审计时由上层保存诊断数据,不能继续依赖运行时永久持有所有历史组件。

生命周期转换使用同步队列展开深依赖链,保留确定性协调和依赖排空后撤回自身效应的规则。不要从多个线程同时修改同一 Context runtime。

SaveOptions.EncodeInBackground 默认关闭。开启后,模块采集和 JSON 快照物化仍在调用线程执行,后台只编码独立快照与加密。CollectTimings 提供采集、编码、加密、落盘阶段数据;存档格式、原子替换和备份回退保持兼容。

从包源升级

Unity 在 Packages/manifest.json 配置 ShrinkSDK scoped registry,使用明确版本号安装:

{
  "scopedRegistries": [{
    "name": "ShrinkSDK",
    "url": "https://git.crash.work/api/packages/ShrinkSDK/npm/",
    "scopes": ["com.cneicy"]
  }]
}

保留工程已有的 registry 和第三方依赖。核心版本为 Context 0.3.0、EventBus 2.2.2、Network 0.4.2、DataSaver 2.4.0、UPM CodeGen 0.2.1;按需添加 com.cneicy.shrink-inspection 0.1.0 与 com.cneicy.shrink-network-messagepack 0.1.0。完整版本以仓库版本目录及 Gitea 包列表 为准。

.NET 使用 https://git.crash.work/api/packages/ShrinkSDK/nuget/index.json 作为 NuGet 源。CLI 安装见 工具说明。

MessagePack 适配包要求消费项目提供 MessagePack-CSharp 与生成式 formatter,避免重复安装二进制。适配器使用 .NET 3.1.8,已验证 Unity 3.1.10 生成 formatter 的字节互通。

升级后由 Unity Package Manager 解析依赖,等待编译完成并确认包来源为 registry。导出 compilation inputs 后,再从实际宿主导出 runtime snapshot;未注册宿主的实例不在默认快照覆盖内。编译、消息互通和实际启动应分别验证。

修改 SDK 源码时,可使用 Pack-Local.ps1 和 Install-Unity.py <工程路径> 测试本地构建;这会把目标项目的 ShrinkSDK 依赖改为本地 tarball,正式消费项目应恢复 registry 版本。

回退

  1. 停止 Play Mode,保存当前 manifest、lock 与相关接入代码。
  2. 同步回退使用新版 API 的业务接入与依赖版本,由 Unity 重建 lock;不手工修改 Library。
  3. 客户端和使用 ShrinkNetworkService 的服务端共同回退。v1/v2 不兼容,不可只回退单边;自定义 transport 协议按其独立策略处理。