59 lines
6.3 KiB
Markdown
59 lines
6.3 KiB
Markdown
# 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` 提供采集、编码、加密、落盘阶段数据;存档格式、原子替换和备份回退保持兼容。
|
||
|
||
## 本地安装与消费工程迁移
|
||
|
||
本次未发布 registry 或 Git tag。UPM 通过工作区当前源码生成便携 tarball,NuGet 通过本地 feed 安装,不将相同版本的旧全局缓存当作新包验证。
|
||
|
||
~~~powershell
|
||
python -X utf8 Tools/AgentSupport/Install-Unity.py D:/UnityBuilds/justanyproject --messagepack
|
||
pwsh Tools/AgentSupport/Pack-Local.ps1
|
||
~~~
|
||
|
||
安装器只更新 manifest 的 ShrinkSDK 依赖,包保存在消费工程 Packages/ShrinkSDK。首次原 manifest 备份在 SDK 的 Artifacts/AgentSupport/justanyproject-manifest-before.json。Unity 执行 PackageManager.Client.Resolve,再等编译稳定;最后核对已安装源码与工作区,不仅检查版本字符串。
|
||
|
||
justanyproject 本次安装 22 包,包括 Inspection 0.1.0 和可选 MessagePack adapter 0.1.0;Context 0.3.0、EventBus 2.2.2、Network 0.4.2、DataSaver 2.4.0、UPM CodeGen 0.2.1。项目已有 MessagePack 3.1.10 与生成器继续保留,adapter 已用其实际 formatter 与 .NET 3.1.8 golden frame 做字节互通验证。不要重新安装冲突的 MessagePack 二进制。
|
||
|
||
新增消费侧内容仅为 Assets/Editor/ShrinkInspection 的宿主快照接入、Assets/Tests/ShrinkSDK 的生成 codec fixture 和三个业务能力 README;没有借此次安装覆盖既有玩法、UI、场景或资源修改。自定义 Endless raw TCP 协议 29 不经过 ShrinkNetworkService v2,不需要为了 SDK 编号而改其协议。
|
||
|
||
进入 Entry 后先导出 compilation inputs,再导出 runtime snapshot。接入记录实际应用 Context/Loader 以及 Network/Command 服务;未注册宿主的实例不在默认快照覆盖内。
|
||
|
||
### 回退
|
||
|
||
1. 停止 Play Mode,备份当前工作区与本次 manifest;不要重置消费工程已有未提交工作。
|
||
2. 将本次新增的 Inspection 编辑器接入、ShrinkSDK codec 测试源及其 asmdef/meta 一并从 Assets 移到工程外备份,避免旧依赖缺少新类型时阻断编译;不移动已有游戏文件。
|
||
3. 恢复安装前 manifest,运行 PackageManager.Client.Resolve,由 Unity 重建对应 lock/cache;保留原 tarball 以便再次安装,不手工编辑 Library。
|
||
4. 客户端和使用 ShrinkNetworkService 的服务端共同回退。v1/v2 不兼容,不可只回退单边。纯自定义 transport 协议按其独立策略处理。
|
||
|
||
新 manifest/lock、便携包和接入源应作为一个本地交付单元保存。消费工程 .gitignore 已对 Packages/ShrinkSDK 的 tarball 放行,避免 manifest 引用被忽略而没有一起保存的文件。版本目录仍以正式发布流程为准,Inspection/可选 MessagePack 的新增包图另做本地检查;旧发布检查器并未自动替这两个新增入口提供远程发布保证。
|
||
|
||
验证结果和三项既有业务测试失败详见 AgentSupportAcceptance.md;本地编译与主场景启动不替代完整多人业务回归。
|