3.1 客户端-服务端架构

模型: claude-opus-4-6 (anthropic/claude-opus-4-6) 生成日期: 2025-02-17


3.1.1 为什么 CLI 工具也需要 Server?

这可能是很多人看到 OpenCode 源码时的第一个疑问:一个运行在终端里的 CLI 工具,为什么要内嵌一个 HTTP Server?

答案在于 OpenCode 的多端架构愿景。虽然终端是主要交互方式,但 OpenCode 同时支持 Web UI、VSCode 扩展、桌面应用等多种前端。这些前端都需要与 OpenCode 的核心引擎通信——而 HTTP API 是最通用、最标准的通信方式。

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│   TUI (Ink)  │  │  Web UI      │  │  VSCode Ext  │
│   终端界面    │  │  浏览器界面   │  │  编辑器扩展   │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       │                 │                 │
       │     HTTP API + SSE Events         │
       │                 │                 │
       └─────────────────┼─────────────────┘

              ┌──────────▼──────────┐
              │   Server (Hono)     │
              │   端口 4096          │
              │                     │
              │   ┌───────────────┐ │
              │   │ Core Engine   │ │
              │   │ Session/Tool/ │ │
              │   │ Agent/Provider│ │
              │   └───────────────┘ │
              └─────────────────────┘

这种设计带来了几个重要的好处:

  1. 前端无关性:核心引擎不需要知道谁在调用它。TUI、Web UI、VSCode 扩展使用完全相同的 API。

  2. 可测试性:可以用标准的 HTTP 测试工具对 API 进行自动化测试。

  3. 远程访问:理论上,OpenCode Server 可以运行在远程服务器上,用户通过浏览器或本地客户端连接。

3.1.2 Server 的实现:基于 Hono 框架的路由系统

OpenCode 使用 Hono 作为 HTTP 框架。从 server/server.ts 的导入可以看到:

衍生概念:Hono

Hono 是一个超轻量级的 Web 框架,最初为 Cloudflare Workers 设计,但也支持 Bun、Deno、Node.js 等运行时。它的 API 设计类似 Express,但性能更好、类型支持更强。选择 Hono 而非 Express 与 OpenCode 选择 Bun 作为运行时是一致的——追求现代、高性能的技术栈。

Server 的默认监听地址是 http://localhost:4096。启动时,核心引擎的所有模块都会初始化,并通过路由系统暴露 API。

3.1.3 API 路由一览

server/routes/ 目录可以看到,Server 提供了 12 个路由模块:

主要 API 端点(参照 specs/project.md):

这是一套完整的 RESTful API,覆盖了 OpenCode 的所有核心操作。

3.1.4 Server-Sent Events(SSE)实时推送机制

在 AI 对话场景中,LLM 的响应是流式的——一个字一个字地生成。这意味着 HTTP 的传统请求-响应模式不够用,需要一种服务端主动推送的机制。

OpenCode 使用 Server-Sent Events (SSE) 来实现这一点。

衍生概念:什么是 SSE?

Server-Sent Events 是 HTML5 的一种标准技术,允许服务端通过一个持久的 HTTP 连接向客户端单向推送事件。

SSE vs WebSocket

特性
SSE
WebSocket

方向

单向(服务端→客户端)

双向

协议

标准 HTTP

独立协议 (ws://)

重连

自动

需要手动实现

兼容性

几乎所有浏览器和 HTTP 客户端

需要特殊支持

适用场景

服务端事件推送、流式数据

实时双向通信(如聊天室)

对于 OpenCode 的场景——服务端推送 LLM 的流式响应和各种事件通知——SSE 是完美的选择:简单、可靠、基于标准 HTTP。

从源码中可以看到 SSE 的使用:

当前端(TUI 或 Web UI)连接到 Server 后,会建立一个 SSE 连接。Server 通过这个连接推送以下类型的事件:

  • 消息更新:LLM 生成的文本增量(delta)

  • 思考链更新:LLM 的推理过程(reasoning)

  • 工具调用事件:工具开始执行、执行完成

  • 权限请求:Agent 需要用户授权

  • 会话状态变更:忙碌/空闲/错误

事件通过 Bus(事件总线)从核心引擎传播到 Server,Server 再通过 SSE 推送给前端。这形成了一条完整的事件传播链:

Last updated