外观
Go SDK 行为参考
包名 neomega,module 为 github.com/OmineDev/neomega-sdk-go,Go 1.23+。公开工具包内的独立模块不依赖私有 Host。开始使用见Go Worker 教程;基础 Worker 协议要求 Host API 1.9、wire 1.0;1.1.0 新增的 Scope、远程会话与投影要求配套 Host API 1.10。
Peer 与连接
Open(ctx) (*Peer, error) 读取 Host 提供的传输参数,完成连接和 hello。默认 stdio;unix 使用绝对 socket 路径;tcp-loopback 只接受 loopback IP。socket 使用 Host 提供的 token,插件不能自行替换安装身份。连接及握手共享最多 10 秒预算,不自动重连。Windows 不支持 unix。
Peer.Call(ctx, method, payload) (map[string]any, error) 是底层 RPC;优先使用下面的封装。Session() 返回安装握手信息,游戏 session 应从 capabilities.get 获取,两者不能混用。Close() 关闭连接,Done() 与 Err() 提供结束状态。
NewPeer(reader, writer) 用于自行接入同一受管协议;Handshake、NextRequest、NextEvent、NextNotification、Respond 和 Reject 是底层接口。使用 Worker.Run 后不要再由另一段代码消费相同消息队列。
生命周期与并发
NewWorker(peer, Callbacks{...}) 返回单次使用的 Worker,Run(ctx) error 拥有连接和 Spawn 注册的后台任务。
| 回调 | 参数及语义 |
|---|---|
Validate | (context.Context, *Peer, map[string]any) (map[string]any, error);只验证配置/状态,可返回 Bus 导出声明 |
Activate / Drain | (context.Context, *Peer, map[string]any) error;开始活动工作 / 完成排空 |
Event | 同上;串行处理事件,返回成功不自动 ACK |
Bus / Service | Bus 返回 (any, error) 的 tagged value;Service 与 Validate 相同签名,返回在线服务结果 map |
Maintenance | 与 Validate 相同签名;原 token 绑定的 seal/release 协作维护 |
前四个生命周期回调 Validate、Activate、Drain、Event 不可缺失。Validate 无导出时返回 nil, nil;非 nil 返回必须包含 "bus_exports": []any{...}。不得在 Validate 开始计时器或其他活动工作。
Spawn(func(context.Context) error) error 最多接纳 32 个受管任务,只在激活或活动期间开放;非协作取消错误会使 Run 失败。Bus 回调可并发,Worker 同时最多接纳 16 个服务调用;共享 Go 状态自行同步。
Drain 等待此前接纳的事件与在线服务,取消受管 Bus/后台活动并实际等待退出,再调用 Drain 回调。成功后恢复接纳,不会再次调用 Activate;要恢复的计时器需在后续事件等明确入口重新创建。不响应取消的 goroutine 仍需 Host 进程终止边界,SDK 不伪造成功排空。
Maintenance 未注册时返回 unsupported。注册后按请求 operation 返回 sealed 或 released,也可返回 busy/unsupported,并原样返回 token。失败返回 maintenance_failed;维护回调不代表自动完成业务状态备份。
配置、KV 与 durable ACK
LoadConfig(dst any) error 优先读取 NEOMEGA_CONFIG_OVERRIDE_FILE,否则读取安装数据目录的 config.json。文件缺失保留预设默认值;内容必须是单个 JSON object、最多 256 KiB。解析拒绝 struct 未知字段和尾随 JSON;读取失败不会静默改用其他配置。
Storage{Peer: peer} 提供下列操作:
| 方法 | 返回及约束 |
|---|---|
Snapshot(ctx, keys) | Snapshot{Revision, Values, Session};Values 为 map[string]json.RawMessage,revision 是全局 CAS revision |
SetValue(key, value) / DeleteKey(key) | 生成 Mutation;写 JSON null 与删除是不同操作 |
PrepareCommit(id, snapshot, mutations, actions, event) | 零 IO 冻结 Intent;actions 只能是同 session 的 operation intent |
Submit(ctx, intent) / Receipt(ctx, id) | 提交一次 / 查询原 commit;不自动重试 |
Ack(ctx, id, snapshot, event) | 返回 (Intent, receipt, error),只 ACK 也使用 CAS,错误时仍保留 Intent |
PrepareCommit 的 ID 仅允许 1–128 个字母、数字、下划线或连字符,提交 JSON 上限 256 KiB。event 为 nil 时使用 state.commit;提供 EventDelivery{SubscriptionID, EventID, DeliveryToken} 时使用 events.commit,同事务提交状态、动作意图和事件进度。三个事件身份字段必须取自原投递,不能重新编造。
订阅写在 manifest 的 subscriptions;SDK 没有自行发明的订阅 RPC。CAS 冲突后不要只换 revision 重放旧业务决定。回执包含原 commit ID、revision、duplicate 和 operation IDs;保留这些证据查询原结果。
游戏操作与不确定结果
Operations{Peer: peer, Session: gameSession} 使用 capabilities.get 的游戏 session。
Prepare(operation, arguments, key, deadline)冻结原 session、幂等键、期限及参数,不发送请求。Submit(ctx, intent)提交一次并返回包含operation_id/state/duplicate的接纳回执。Get(ctx, operationID)查询原回执;Cancel(ctx, operationID)显式请求取消。
接纳不代表游戏效果完成。context 取消只是停止等待,不撤销已接纳动作;显式取消也不能宣称撤销已发送效果。unknown 保持不确定,禁止自动重放或替换 ID。
传输失败或回执不合法时可能返回 *Uncertain,其中 Intent 保留原请求、ID 保留已知 ID、Err 保留原因。Host 明确拒绝通过 *IPCRejected{Code, Retryable} 返回;Retryable 字段不授予业务自动重试许可。错误不意味着请求未发送。
跨进程恢复前持久保存 Intent.Method() 与 Intent.Payload()。RestoreIntent(method, payload) 只恢复 state.commit/events.commit/operations.submit 的请求数据,不提交,不刷新期限或 ID。先用 Storage.Receipt 或 Operations.Get 对账;旧 unknown、journal 与 receipt 不应被恢复流程改成成功。
Bus read/service 消费与导出
Bus{Peer: peer}.Catalog(ctx) 返回目录。BusRequest 显式包含 Target、Major、SchemaDigest、Args、Deadline、Kind,可带 Provider 与 Cause。Target、major、digest 和 tagged args 从目录合同取得;SDK 不会把任意 Go struct 自动推断成匹配合同。
| 方法 | 行为 |
|---|---|
Submit(ctx, request) | 仅支持 read/service,必须给出 Deadline;返回原 call receipt |
Get(ctx, id) / Cancel(ctx, id) | 查询 / 显式取消原 call ID |
Wait(ctx, receipt, poll) | poll 必须大于零;到终态或 context 结束,错误时保留最后回执,不隐式取消 |
Result(ctx, receipt) | 只解码 succeeded 结果,不修改原回执 |
Call(ctx, request, poll) | 一次提交、等待、解码;返回 (receipt, value, error),终态失败仍保留 receipt |
Wait 的终态为 succeeded/failed/cancelled/deadline_exceeded/unavailable;取消或 deadline 结果仍需关注 actual_done,不能据此推断提供者代码已经退出。需要远端取消时,使用单独有效的清理 context 调用 Cancel。
导出时由 Validate 返回 bus_exports:每项提供 name/member/kind/major/shared/candidate_readable/contract,其中 contract 包含 major/schema_digest/schema,并在 manifest 中声明相同导出;Callbacks.Bus 处理 Host 鉴权后的调用。kind=read 且 candidate_readable=true 的声明可在激活前接受候选只读调用,不能借此写游戏状态。Bus 回调应响应 Host 传入的 deadline 与取消。Go SDK 不提供 View/Publish 流提供者,bus.streams.start 返回 provider_unavailable。
Bus 消费按精确成员声明 permissions.services,管理员授予 service:<member>;manifest 声明不等于已有授权。游戏 operation 使用对应 operation 权限,事件使用对应订阅和事件权限,不能用 Bus 服务 grant 替代。权限参考与Bus 合同说明 Host 侧约束。
值编码与 bulk
DecodeJSON 保留数字为 json.Number,拒绝重复 object key、非 UTF-8、尾随数据及超限输入;EncodeJSON 使用同一限制。单值最多 16 MiB,嵌套最多 256 层、节点最多 1,000,000。整数宽度、float bit pattern、NBT 等继续使用目录定义的 tagged value,不以 float64 中转整数。
EncodeBusValue(ctx, peer, value, deadline) 与 DecodeBusValue(ctx, value) 处理内联值或 Host 有界 bulk 引用。UploadBulk / DownloadBulk 只消费 Host 发放的 descriptor;不要把 base64 字符串当作任意协议的通用二进制包装。Bus Submit/Result 已接入这条路径。
完整公开类型、函数及方法声明见 Go API 目录。
1.1.0 资源会话与观察
这些包包含在公开 sdk/go 中,沿用同一 module,无需导入私有框架包。Worker 用 neomega.NewManagedBus(peer) 将已有连接适配成 typed Bus,再传给 scopes.New 或 busview.OpenProjection;适配器借用 Peer,调用方仍负责关闭所有 Scope 与观察流。
| 包 | 能力与用法 |
|---|---|
scopes | 手动 Acquire/AcquireRequest、单次回调 Run、续租、关闭与证据;见Go 资源会话。 |
bushttp | Config、New 和原动作 Operation 查询;与 scopes.NewRemote 组合,见Go 远程客户端。 |
busview | OpenProjection、Snapshot/Read/Close 与后台恢复;见Go 可恢复投影。 |
busapi | typed Bus 的合同、请求、动作意图、View 与 Scope 句柄。 |
busvalue | 结构类型绑定、合同摘要及 tagged 值编解码;按成员目录核对合同。 |
Scope 不替代业务权限,不提供游戏世界回滚。关闭未完成或动作 unknown 时,保存原身份与回执继续核对;不要在重新连接后重新执行业务回调。