开发者文档/开发指南

Backend 与架构

理解 UI、Host 和 Backend 的职责,再通过 Wire Protocol v1 接入原生进程。

核对日期:2026 年 9 月 11 日

本页目录

什么时候需要 Backend#

UI-only Curio 已能通过 Web SDK 使用 Host 注册的服务。当工具需要自己的原生计算、语言运行时、持续任务,或希望向其他 Curio 提供服务时,再加入 Backend。

text
Curio UI → Web SDK → Host service bus → host.* built-in service
                                    → @self (this Curio’s Backend)
                                    → named service (provider Backend)

Host 管理窗口与进程生命周期、连接身份、路由、取消和 Contract 校验。Web SDK 传递请求与事件。Backend 实现自己的方法,并在取消或关闭时清理工作。Backend-only Curio 可以只提供服务,不创建界面。

配置进程#

把以下片段合并到 ID 为 dev.example.text-tools 的 Manifest。开发命令假定你已实现 backend/index.mjs;生产入口需要另外构建:

json
{
  "backend": {
    "entry": "backend/text-tools",
    "lifecycle": "on-demand",
    "transport": "unix",
    "startWithUi": true
  },
  "development": {
    "backend": {
      "mode": "managed",
      "command": ["node", "backend/index.mjs"]
    }
  }
}

已有 UI 服务时保留 development.ui。managed 模式由 Host 启动命令;external 模式由你使用 .trove/dev-session.json 与支持该会话文件的连接逻辑,手动启动进程。

Node 只是开发运行时示例。Host 不捆绑 Node 或 Python。当前分发 Backend 需要目标平台上的自包含原生可执行文件。CLI 仅提供 Web、static 模板,没有可用的 --template node--template rust

通过 Wire Protocol v1 连接#

Backend 连接 TROVE_SOCKET_PATH 指定的 Unix Domain Socket,使用 TROVE_SESSION_TOKEN 认证。token 和开发会话文件都是凭据,不提交到仓库,也不写入日志。

每条消息是 UTF-8 JSON,前面加 4 字节无符号大端 payload 长度。它不是按行分隔 JSON、HTTP 或 WebSocket。接收端必须缓存分片,也要能处理一次读取中的多条帧。当前帧上限 8 MiB,遵守 Host 协商返回的限制。

  1. 连接 socket,发送携带 token 和支持版本范围的 hello。
  2. 收到 welcome,检查协议版本,并读取 session、features、limits。
  3. 服务确实能处理请求后,再发送 ready。
  4. 按 ID 处理请求、响应、订阅和取消。
  5. 收到 shutdown 后停止工作,发送 goodbye 并关闭连接。
json
{
  "v": 1,
  "type": "hello",
  "client": "backend",
  "sessionToken": "REPLACE_WITH_HOST_SESSION_TOKEN",
  "protocol": { "min": 1, "max": 1 },
  "features": ["call", "cancel"],
  "implementation": { "name": "my-backend", "version": "0.1.0", "language": "rust" }
}

这是加帧头前的 payload 示例,不是可重复使用的 token。Wire 消息 JSON Schema 描述各消息结构;结构合法不代表握手顺序和运行行为正确。

实现私有请求#

Backend 实现方法后,UI 可调用 trove.self.call("uppercase", { text: "hello" }),Host 使用 @self 路由。成功响应必须带回收到的请求 ID:

json
{
  "v": 1,
  "type": "response",
  "id": "INCOMING_REQUEST_ID",
  "result": { "text": "HELLO" }
}

result 与 error 必须且只能出现一个。error 包含稳定的 code 和可读的 message,可附 data、retryable、traceId。请求可能并发执行、乱序完成,要根据 ID 对应响应,不能依赖到达顺序。收到 cancel 时尽可能停止对应任务。

反向调用 Host 并继续同一调用链时,保留 Host 提供的请求 context,不伪造调用者身份。公共命名服务还需要 Contract 与 Manifest 声明

验证协议与生命周期#

sh
trove protocol test --command node -- backend/index.mjs

也可以执行 trove protocol test,使用工程配置的 Backend 命令。测试创建临时隔离会话,验证握手、分片帧、并发响应、结构化错误和正常关闭。当前探针并发发送八次 @self.__trove_conformance_unknown_method__,要求每次返回匹配 ID 的结构化错误,并在 shutdown 后正常退出进程,整体限时 20 秒。

协议探针验证互操作行为,不能替代业务测试。还应验证真实 UI 调用、运行中取消、on-demand Curio 的关闭与重开,以及安装包不依赖开发运行时。