外观
编写 Go Worker
Go Worker 是由 Host 管理的独立进程:安装、配置、权限、事件和更新走同一套插件管理入口。使用 Go 1.23+ 编译,运行二进制不需要 Python;管理工具使用的 Python 环境另行配置。需要 Host API 1.9、Worker wire 1.0。
从工具包取得 sdk/go 与 examples/go-worker。SDK 的 module 名为 github.com/OmineDev/neomega-sdk-go,只依赖标准库。示例的 go.mod 使用 replace ... => ../../sdk/go,保留这两个目录的相对位置即可构建,不需要私有 Host 源码,也无需先从 module 代理下载 SDK。
1.1.0 还提供资源会话、远程 EP和可恢复投影。这些新能力需要 Host API 1.10,与基础 Worker 的 1.9 门槛区分。
1. 阅读状态服务示例
examples/go-worker/main.go 是可修改的完整入口。它订阅 chat.received,把聊天计数和 durable ACK 放在同一个 CAS 提交中;同时导出原生 Bus go_state.count(候选可读 read)和 go_state.inspect(活动 service),两者为 EmptyRequest → u64。另保留在线服务 plugin.<manifest.id>.count 返回 label 与 count,major 为 1、参数为 {}。它不发送游戏动作。
| 回调 | 示例行为 |
|---|---|
Validate | 加载配置,检查已有计数能否解码;不开始后台工作 |
Activate | 接受激活;该示例无需额外后台任务 |
Event | 读取 revision,以原 delivery token 派生 commit ID,原子提交计数和 ACK |
Bus / Service | Bus 返回 tagged u64 计数;manifest exports 在线服务返回 label 与 count |
Drain | 由 SDK 完成受管调用排空后返回 |
config.example.json 是配置模板,不会自动写入安装配置。LoadConfig 读取 Host 选择的配置;先给 Go struct 设置默认值。配置字段同时维护 config.schema.json。
Python 消费者在 permissions.services 声明 go_state.inspect 并取得对应授权后,可在激活阶段调用:
python
from neomega_runtime import u64
count = await ctx.bus.call("go_state.inspect", result_type=u64,
kind="service", major=1, timeout=5)bus-contract.json 固定 EmptyRequest → u64 的结构和摘要,并通过 Go embed 编译进二进制;自行改变入参或结果时须同步更新合同、manifest 和回调。
2. 为目标平台构建
在 examples/go-worker 内执行对应命令,每个 ZIP 只放一个目标平台的产物:
| 平台 | 构建命令 |
|---|---|
| Linux x64 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOWORK=off go build -trimpath -o worker . |
| Linux ARM64 | CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GOWORK=off go build -trimpath -o worker . |
| Windows x64 | CGO_ENABLED=0 GOOS=windows GOARCH=amd64 GOWORK=off go build -trimpath -o worker.exe . |
| macOS Intel | CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 GOWORK=off go build -trimpath -o worker . |
| macOS Apple Silicon | CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 GOWORK=off go build -trimpath -o worker . |
表中是 POSIX shell 命令,可交叉编译 Windows 产物。原生 PowerShell 使用 $env:GOOS="windows"、$env:GOARCH="amd64"、$env:CGO_ENABLED="0"、$env:GOWORK="off" 设置相同变量后执行 go build。
同步修改 manifest 的 target_os、target_arch 与 entrypoint。源码模板的 manifest 是 Linux amd64;下载的五平台发行包会将示例 manifest 与二进制一并设置为该包目标平台。以手中包内的 target_os/target_arch 为准;自行交叉编译时同步修改这两项。Windows 入口为 worker.exe。入口必须是包内安全相对路径,Host 直接执行它,不经 shell。平台不匹配会报告 worker_platform_mismatch。
json
{
"runtime": "go",
"target_os": "linux",
"target_arch": "amd64",
"entrypoint": "worker",
"host_api": {"major": 1, "min_minor": 9},
"worker_protocol": {"major": 1, "min_minor": 0}
}这是需核对的字段片段;完整包继续保留示例 manifest 中的身份、订阅、权限、状态版本与 exports。发布时给自己的插件设置唯一 ID。Host 发行包内的预构建示例使用 example.go-state-<os>-<arch>,不要混用不同平台的 manifest 与二进制。
3. 打包并安装
新建单独目录 plugins/go-state,放入目标二进制、完整 manifest.json、config.schema.json 与 config.example.json,再创建 package.files.json:
json
["worker", "manifest.json", "config.schema.json", "config.example.json"]Windows 将清单中的 worker 改为 worker.exe。pack 必须读取这份显式清单,只收录清单中的文件;清单本身无需加入 ZIP。bus-contract.json 已编译进二进制,无需作为运行文件收录。不要收录配置实值、数据目录或凭据。
从工具包目录执行:
sh
python3 runtime-plugins.py pack plugins/go-state go-state.zipZIP 保存在插件目录外。安装沿用第一个插件的管理员控制台流程:安装包、配置、核对并授予申请权限、启用和启动。该示例需要活动游戏 session 才能接收聊天事件。Go 二进制随目标平台分发,不能把源码包当作可执行插件安装。
4. 接入自己的业务
需要多个动作共用资源时,使用 scopes.New(neomega.NewManagedBus(peer)) 接入同一 Worker 连接,再按资源会话示例申请和关闭;需要连续观察时,将同一个适配器交给 busview.OpenProjection。插件停止前先关闭这些资源,最后结束 Worker。
入口使用 Open(ctx),把 Peer 交给 NewWorker(peer, callbacks).Run(ctx)。Validate、Activate、Drain、Event 都必须提供;可选 Service、Bus 和 Maintenance。日志写 stderr,stdout 留给协议。后台协作任务通过 worker.Spawn 注册并响应 context 取消;自行创建的 goroutine 不会自动变成受管工作。
事件成功返回不等于 ACK。需要状态与 ACK 一起推进时使用 PrepareCommit(..., &event);只提交 ACK 时使用 Storage.Ack。revision 冲突与回执不确定都应保留原 commit ID,查询 Storage.Receipt 后对账,不自动重试。
Bus 的 read/service 调用、导出合同和游戏操作回执见 Go SDK 行为参考。runtime-task 继续使用 Python;需要 Go 进程内 Frame 模块时走原生 Go 模块。Go Worker SDK 不提供 View/Publish 流提供者接口。