Skip to content

消息通信机制 ​

本文引用的源码文件

本文引用的文件

目录 ​

  1. 引言
  2. 项目结构与通信边界
  3. Chrome 扩展消息模型:sendMessage 与 onMessage
  4. Content Script 到 Background Service Worker 的消息路由表
  5. 扩展端与 Agent 端的 HTTP/WebSocket 通信契约
  6. 从网页脚本调用后台功能的端到端流程
  7. 超时、重试与连接状态管理
  8. 架构总览图
  9. 故障排查指南
  10. 结论

引言 ​

本文面向 Chrome Extension(Manifest V3,版本 2.3.1)与独立本地 Agent(Node.js,版本 2.3.1)的双进程架构,系统性说明以下能力:

  • chrome.runtime.sendMessage 与 chrome.runtime.onMessage 的同步/异步使用方式。
  • Content Script 中基于 Map 的消息路由表结构及 O(1) 分发逻辑。
  • Background Service Worker 作为扩展内部消息中枢的职责。
  • 扩展端通过 local-agent-client.js 与 Agent 端 server.js 之间的 HTTP 与 WebSocket 契约。
  • 消息超时、可达性缓存、SW 保活、Agent 重启等运行时约束。
  • 实际代码路径引用,便于读者直接定位实现。

本项目是双进程架构:Chrome 扩展端位于 src/,Agent 端入口为 agent/src/server.js。两端版本号保持同步,文档以 2.3.1 为准。Agent 源码修改后必须重启进程,新接口才生效。

项目结构与通信边界 ​

扩展端按 MV3 Service Worker 组织,核心通信边界如下:

  • 网页脚本 / Content Script:运行在页面上下文中,负责 DOM 操作、页面信息提取、用户交互。
  • Background Service Worker:扩展全局上下文,负责消息路由、工具调度、Agent 客户端封装、侧边栏控制、定时任务等。
  • Side Panel / Options / Offscreen:扩展 UI 层,通过 chrome.runtime.sendMessage 与 Background 通信。
  • Agent 服务:独立 Node.js 进程,提供文件系统、命令执行、Skill、MCP、RAG 等能力,暴露 HTTP API 与 WebSocket。
graph TB
WebPage["网页脚本"] --> ContentScript["Content Script<br/>src/content/index.js"]
ContentScript --> Background["Background Service Worker<br/>src/background/index.js"]
SidePanel["Side Panel / Options"] --> Background
Background --> AgentClient["Agent 客户端<br/>src/background/local-agent-client.js"]
AgentClient --> AgentServer["Agent 服务端<br/>agent/src/server.js"]

图表来源

章节来源

Chrome 扩展消息模型:sendMessage 与 onMessage ​

同步消息 ​

当接收方在 onMessage 处理器中直接调用 sendResponse(result) 并返回 undefined 时,发送方的回调立即拿到结果。适用于轻量、无网络 IO 的操作。

示例路径:

  • Content Script 同步处理简单查询类消息。
  • Background 向 Side Panel 或 Options 广播状态变更。

参考实现位置:

异步消息 ​

当处理器返回 true,或通过 Promise 调用 sendResponse,表示消息通道保持开放,后续再回复。适用于:

  • 需要等待 DOM 操作完成。
  • 需要等待网络请求或子任务完成。
  • 需要维持长连接(如 keepalive port)。

参考实现位置:

关键行为总结 ​

场景发送方接收方返回值约定
轻量同步响应chrome.runtime.sendMessage(msg, cb)onMessage 中直接 sendResponse(data)同步返回
异步响应chrome.runtime.sendMessage(msg, cb)onMessage 中 Promise.then(sendResponse) 并返回 true延迟回复
长连接chrome.runtime.connect(portName)onConnect 监听端口双向 postMessage
跨 Tab 定向chrome.tabs.sendMessage(tabId, msg)目标 Tab 的 Content Script onMessage同 sendMessage

章节来源

Content Script 到 Background Service Worker 的消息路由表 ​

Content Script 使用一个集中式 HANDLERS Map,将 message.type 映射到具体处理器函数。该设计具备以下特点:

  • O(1) 查找:通过对象键直接定位处理器。
  • 分类清晰:页面读取、页面交互、表单输入、信息提取、媒体输出、异步工具等分组明确。
  • 异步标记集合:ASYNC_HANDLERS 声明哪些类型需要保持消息通道开放。
  • 顶层帧限制:TOP_FRAME_ONLY_TYPES 避免 iframe 抢占响应。
flowchart TD
Start["收到 chrome.runtime.onMessage"] --> CheckTop["是否 TOP_FRAME_ONLY 且非顶层帧?"]
CheckTop --> |是| Ignore["忽略消息"]
CheckTop --> |否| Lookup["HANDLERS[message.type]"]
Lookup --> Found{"找到处理器?"}
Found --> |否| Exit["不处理"]
Found --> |是| CallHandler["调用 handler(message)"]
CallHandler --> AsyncCheck{"是否 ASYNC_HANDLERS 或返回 Promise?"}
AsyncCheck --> |是| KeepOpen["return true<br/>Promise.then(sendResponse)"]
AsyncCheck --> |否| SyncReply["sendResponse(result)"]

图表来源

路由表分类摘要 ​

类别典型 message.type职责
页面读取GET_PAGE_TEXT、GET_FULL_HTML、QUERY_ELEMENTS、GET_SELECTED_CONTENT获取文本、HTML、可交互元素、选区内容
页面交互INTERACT_ELEMENT、FILL_FORM、SCROLL_TO点击、填表、滚动
表单输入KEYBOARD_INPUT、FILE_UPLOAD键盘输入、文件上传
信息提取EXTRACT_TABLE、EXTRACT_METADATA、EXTRACT_LINKS、EXTRACT_FORMS、EXTRACT_IMAGES、SEARCH_IN_PAGE、IFRAME_CONTENT、SCROLL_COLLECT结构化数据抽取
媒体输出MANAGE_STORAGE、INJECT_CSS存储管理与样式注入
异步工具COPY_TO_CLIPBOARD、PASTE_FROM_CLIPBOARD、WAIT_ELEMENT、SELECT_DROPDOWN、QRCODE、START_REGION_SELECTION需要等待或 UI 交互的工具

章节来源

扩展端与 Agent 端的 HTTP/WebSocket 通信契约 ​

总体契约 ​

扩展端通过 local-agent-client.js 统一封装对 Agent 的 HTTP 与 WebSocket 调用;Agent 端由 server.js 提供 HTTP Router 与 WebSocket 支持。所有需认证的请求携带 Authorization: Bearer <token>。

sequenceDiagram
participant BG as "Background Service Worker"
participant Client as "local-agent-client.js"
participant Agent as "agent/src/server.js"
BG->>Client : 调用 execCommand / readFile / getMcpTools 等
Client->>Client : agentRequest(path, body, method, timeoutMs)
Client->>Agent : fetch(url, { Authorization : Bearer token })
Agent-->>Client : JSON { success, ... }
Client-->>BG : 返回结果或错误

图表来源

HTTP 端点分类 ​

领域端点方法说明
配对与会话/api/pairPOST扩展与 Agent 配对,返回 token
健康检查/api/statusGET返回版本、平台、RAG 可用性等
详细状态/api/status/detailGET工作目录、资源使用、进程列表等
文件系统/api/fs/read、/api/fs/write、/api/fs/list、/api/fs/delete、/api/fs/search_files、/api/fs/search_contentPOST文件读写、目录浏览、搜索
文件上传/api/files/uploadPOSTmultipart/form-data 上传
命令执行/api/execPOST启动命令,支持 wait、timeoutMs
命令停止/api/exec/stopPOST停止运行中的命令
MCP/api/mcp/tools、/api/mcp/call、/api/mcp/servers/*GET/POST/DELETE/PUTMCP 工具与服务端管理
Skill/api/skill/*GET/POST/DELETESkill 列表、详情、执行、导入、启用/禁用
Agent 管理/api/agent/restart、/api/agent/update、/api/shutdownPOST重启、更新、关闭

章节来源

WebSocket 契约 ​

WebSocket 用于命令执行的实时输出流。扩展端通过 createExecWebSocket(wsUrl, onMessage, onClose, onError) 建立连接,Token 通过 URL 参数附加。

关键点:

  • Token 从当前活跃 Agent 配置中获取。
  • 若 Agent 已知不可达,直接走错误回调,避免无效连接。
  • 空闲超时由调用方统一管理,避免双重超时冲突。
  • 连接成功 resolve WebSocket 实例,失败 reject 并触发 onError。
sequenceDiagram
participant Executor as "tool-executor.js"
participant Client as "local-agent-client.js"
participant WS as "WebSocket"
participant Agent as "agent/src/server.js"
Executor->>Client : createExecWebSocket(wsUrl, onMessage, onClose, onError)
Client->>Client : 校验 connected 与 reachability
Client->>WS : new WebSocket(authenticatedUrl)
WS-->>Client : onopen → resolve(ws)
WS-->>Executor : onmessage(JSON)
WS-->>Executor : onclose → onClose()
WS-->>Executor : onerror → onError(error)

图表来源

认证与安全 ​

  • Agent 端对大多数接口要求 Authorization: Bearer <token>。
  • CORS 仅放行 chrome-extension:// 来源。
  • 配对接口 /api/pair 无需认证,但会记录 extensionId。
  • 心跳接口 /api/heartbeat 刷新在线状态,不返回敏感信息。

章节来源

从网页脚本调用后台功能的端到端流程 ​

以“从网页截图”为例,展示完整链路:

sequenceDiagram
participant Page as "网页脚本"
participant Content as "Content Script"
participant BG as "Background Service Worker"
participant Panel as "Side Panel"
Page->>Content : 快捷键触发 CAPTURE_TAB_FROM_PAGE
Content->>BG : chrome.runtime.sendMessage({ type : 'CAPTURE_TAB_FROM_PAGE' })
BG->>BG : 执行截图逻辑
BG-->>Panel : chrome.runtime.sendMessage({ type : 'SCREENSHOT_RESULT', dataUrl, mode })

图表来源

另一个常见流程是“选项页通知 Background 打开/关闭”:

sequenceDiagram
participant Options as "Options 页面"
participant BG as "Background Service Worker"
Options->>BG : chrome.runtime.sendMessage({ type : 'OPTIONS_PAGE_OPEN' })
BG->>BG : 设置 _optionsPageOpen = true
BG-->>Options : 可选状态广播
Options->>BG : chrome.runtime.sendMessage({ type : 'OPTIONS_PAGE_CLOSED' })
BG->>BG : 设置 _optionsPageOpen = false

图表来源

章节来源

超时、重试与连接状态管理 ​

消息超时 ​

  • HTTP 请求通过 AbortController 实现超时,默认 60 秒,部分接口(如下载)延长至 120 秒。
  • WebSocket 空闲超时由调用方统一管理,避免与连接层双重超时冲突。

参考实现位置:

重试机制 ​

  • 代码未实现自动重试循环,而是通过可达性缓存快速失败,避免阻塞。
  • 用户可通过“触发健康检查”手动刷新状态。

参考实现位置:

连接状态管理 ​

  • Background 维护 _agentReachability 内存缓存,按 agentId 区分可达性。
  • SW 保活通过 side panel 的 keepalive port 防止被系统回收。
  • Agent 重启/更新后需重新配对或刷新 token。

参考实现位置:

章节来源

架构总览图 ​

classDiagram
class ContentScript {
+HANDLERS Map
+ASYNC_HANDLERS Set
+TOP_FRAME_ONLY_TYPES Set
+onMessage(message, sender, sendResponse)
}
class BackgroundServiceWorker {
+onMessage(message, sender, sendResponse)
+keepalivePort(sessionId)
+sidePanelControl()
+agentHealthCheck()
}
class LocalAgentClient {
+agentRequest(path, body, method, timeoutMs)
+agentGet(path, timeoutMs)
+createExecWebSocket(wsUrl, onMessage, onClose, onError)
+getAgentConfig()
}
class AgentServer {
+httpServer(req, res)
+wsServer(connection)
+authMiddleware(token)
+corsFilter(origin)
}
ContentScript --> BackgroundServiceWorker : "chrome.runtime.sendMessage"
BackgroundServiceWorker --> LocalAgentClient : "HTTP/WebSocket"
LocalAgentClient --> AgentServer : "fetch + WebSocket"

图表来源

故障排查指南 ​

常见问题 ​

问题可能原因排查建议
Content Script 消息无响应非顶层帧拦截、handler 未注册、异步未 return true检查 TOP_FRAME_ONLY_TYPES 与 ASYNC_HANDLERS
Background 被系统回收SW 空闲终止、无 keepalive确认 side panel 保活连接存在
Agent 请求超时网络不可达、Agent 未启动、token 失效检查 /api/status 与 Authorization 头
WebSocket 连接失败Agent 重启、token 过期、地址替换异常查看 createExecWebSocket 日志与 reachable 缓存
大消息截断chrome.runtime.sendMessage 单条最大 64MiB使用日志截断逻辑或分片传输

关键日志位置 ​

  • Background:[Background] 前缀日志。
  • Agent:[Agent] 前缀日志。
  • AgentClient:[AgentClient] 前缀日志。

章节来源

结论 ​

本项目的消息通信机制围绕三层展开:

  1. 扩展内部:Content Script 通过集中式路由表与 Background Service Worker 通信,支持同步与异步模式。
  2. 扩展与 Agent:Background 通过 local-agent-client.js 封装 HTTP 与 WebSocket,统一认证、超时与可达性管理。
  3. Agent 服务端:提供 RESTful API 与实时命令输出流,支持文件、命令、Skill、MCP、RAG 等能力。

在实际使用中,应重点关注:

  • 消息类型定义与路由一致性。
  • 异步处理器正确返回 true 或使用 Promise。
  • Agent 连接状态与 token 有效性。
  • SW 生命周期与保活机制。
  • 大消息截断与性能优化。