Doramagic 项目包 · 项目说明书
browser-gateway 项目
生成时间:2026-06-01 03:29:30 UTC
快速入门
browser-gateway 是一个可靠、可扩展的浏览器基础设施,为 AI 代理和应用提供统一的浏览器访问能力。本指南将帮助你在 5 分钟内完成安装、配置和基本使用。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
安装
环境要求
| 要求 | 最低版本 |
|---|---|
| Node.js | 18.x |
| npm/pnpm/yarn | 最新稳定版 |
| Chrome/Chromium | 最新稳定版 |
全局安装
npm install -g browser-gateway
安装完成后,验证版本:
browser-gateway version
# 输出: browser-gateway v0.2.0
资料来源:package.json:3
Docker 部署
docker run -d \
--name browser-gateway \
-p 9500:9500 \
-v $(pwd)/gateway.yml:/app/gateway.yml \
browsergateway/browser-gateway:latest
启动服务
默认启动
最简单的启动方式,不配置任何参数:
browser-gateway serve
服务将在 http://localhost:9500 启动,默认配置如下:
| 参数 | 默认值 |
|---|---|
| 端口 | 9500 |
| CDP 端点 | 自动检测 Chrome |
| 并发限制 | 无限制 |
自定义配置启动
browser-gateway serve --config gateway.yml
资料来源:README.md:50-60
核心使用模式
browser-gateway 支持三种主要使用模式,适用于不同场景:
graph LR
A[使用场景] --> B[REST API]
A --> C[WebSocket]
A --> D[MCP Server]
B --> B1[截图<br/>内容提取<br/>数据抓取]
C --> C1[browser-use<br/>Playwright<br/>Stagehand]
D --> D1[Claude Code<br/>Cursor<br/>AI 代理]模式一:REST API
最简单的方式,通过 HTTP POST 请求即可完成浏览器操作,无需 WebSocket 连接管理。
#### 截图接口
curl -X POST http://localhost:9500/v1/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}' \
--output screenshot.png
#### 内容提取
支持多种格式:markdown、text、html、readability
curl -X POST http://localhost:9500/v1/content \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"formats": ["markdown"]
}'
返回结构:
{
"success": true,
"data": {
"url": "https://example.com",
"statusCode": 200,
"content": {
"markdown": "# 页面标题\n\n页面正文内容..."
},
"metadata": {
"title": "页面标题",
"description": "页面描述",
"author": "作者",
"wordCount": 1234
}
}
}
资料来源:src/server/rest/content.ts:60-80
#### 数据抓取
使用 CSS 选择器精确提取数据:
curl -X POST http://localhost:9500/v1/scrape \
-H "Content-Type: application/json" \
-d '{
"url": "https://news.ycombinator.com",
"selectors": [
{"name": "titles", "selector": ".titleline > a"},
{"name": "scores", "selector": ".score"}
]
}'
资料来源:package.json:3
配置参考
browser-gateway 采用 YAML 配置文件管理所有运行时参数,支持命令行覆盖和环境变量扩展。配置文件路径可通过 --config 参数指定,默认为当前目录下的 gateway.yml。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
配置文件结构
完整配置分为六大模块:服务端口、HTTP 服务器、浏览器提供程序(Providers)、会话池、认证和安全选项。
# 基础配置示例
server:
host: "0.0.0.0"
port: 9500
http:
enabled: true
cors:
origin: "*"
credentials: true
providers: []
pool:
maxConcurrent: 10
sessionTtl: 300
auth:
enabled: false
token: ""
security:
allowedIps: []
rateLimit:
enabled: true
maxRequests: 1000
windowMs: 60000
logging:
level: "info"
format: "json"
服务配置
服务器基础设置
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
server.host | string | "0.0.0.0" | 监听地址 |
server.port | number | 9500 | 监听端口 |
HTTP 服务器
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
http.enabled | boolean | true | 是否启用 REST API |
http.cors.origin | string | "*" | CORS 允许的源 |
http.cors.credentials | boolean | true | 是否允许凭证 |
http.prefix | string | "/v1" | API 路由前缀 |
server:
host: "0.0.0.0"
port: 9500
http:
enabled: true
cors:
origin: "*"
credentials: true
prefix: "/v1"
提供商配置(Providers)
Providers 是浏览器实例的连接定义,支持本地 Chrome 浏览器、云服务或自托管的 Playwright Server。
提供商参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 提供商唯一标识符,使用小写字母和连字符 |
type | string | 是 | 类型:launch、connect 或 ws |
url | string | 是 | WebSocket 连接地址 |
priority | number | 否 | 优先级(数值越小优先级越高),默认 0 |
maxConcurrent | number | 否 | 最大并发连接数 |
labels | string[] | 否 | 标签列表,用于路由匹配 |
提供商类型详解
#### launch 类型
启动本地 Chrome 浏览器,自动检测安装路径。
providers:
- id: "local-chrome"
type: "launch"
url: "http://localhost:9222"
priority: 0
maxConcurrent: 5
labels: ["local", "fast"]
#### connect 类型
连接到已运行的浏览器实例(如 Docker 容器中的 Chrome)。
providers:
- id: "docker-chrome"
type: "connect"
url: "ws://chrome-container:9222"
priority: 1
maxConcurrent: 10
#### ws 类型
连接第三方云浏览器服务。
providers:
- id: "cloud-browser"
type: "ws"
url: "wss://provider.com?token=your-api-key"
priority: 2
maxConcurrent: 20
labels: ["cloud"]
多提供商配置示例
providers:
- id: "local-chrome"
type: "launch"
url: "http://localhost:9222"
priority: 0
maxConcurrent: 5
- id: "playwright-server"
type: "connect"
url: "ws://localhost:3000"
priority: 1
maxConcurrent: 10
- id: "cloud-provider"
type: "ws"
url: "wss://api.provider.com?token=${CLOUD_TOKEN}"
priority: 2
maxConcurrent: 50
会话池配置
会话池(Session Pool)复用浏览器连接以提升性能,支持配置最大并发数和会话生命周期。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
pool.maxConcurrent | number | 10 | 全局最大并发会话数 |
pool.sessionTtl | number | 300 | 会话存活时间(秒),默认 5 分钟 |
pool.idleTimeout | number | 60 | 空闲连接超时时间 |
pool:
maxConcurrent: 10
sessionTtl: 300
idleTimeout: 60
会话复用流程
graph TD
A[新请求] --> B{会话池有空闲连接?}
B -->|是| C[复用已有连接]
B -->|否| D{达到最大并发?}
D -->|否| E[创建新浏览器页面]
D -->|是| F[等待空闲连接]
C --> G[执行操作]
E --> G
F --> G
G --> H{请求完成}
H --> I[连接返回池中]
I --> J[TTL 计时]
J --> K{超时?}
K -->|是| L[释放连接]
K -->|否| B会话重连
断开连接后可使用 ?sessionId= 查询参数重新连接到同一浏览器会话,保留 Cookies、localStorage 和页面状态。
# 重连会话
wscat "ws://localhost:9500/v1/connect?sessionId=abc123"
认证与安全
认证配置
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
auth.enabled | boolean | false | 是否启用认证 |
auth.token | string | - | 访问令牌 |
启用认证后,仪表板需要通过安全 HttpOnly Cookie 进行身份验证。
auth:
enabled: true
token: "your-secure-token"
安全限制
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
security.allowedIps | string[] | [] | 允许的 IP 地址列表 |
security.rateLimit.enabled | boolean | true | 是否启用速率限制 |
security.rateLimit.maxRequests | number | 1000 | 时间窗口内最大请求数 |
security.rateLimit.windowMs | number | 60000 | 时间窗口(毫秒) |
security:
allowedIps:
- "127.0.0.1"
- "10.0.0.0/8"
rateLimit:
enabled: true
maxRequests: 1000
windowMs: 60000
日志配置
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
logging.level | string | "info" | 日志级别:debug、info、warn、error |
logging.format | string | "json" | 日志格式:json、text |
logging.file | string | - | 日志文件路径(可选) |
logging:
level: "info"
format: "json"
file: "/var/log/browser-gateway.log"
环境变量
配置文件中支持使用 ${ENV_VAR} 语法引用环境变量。
providers:
- id: "cloud"
type: "ws"
url: "wss://api.provider.com?token=${BROWSER_TOKEN}"
auth:
token: "${BG_TOKEN}"
常用环境变量
| 变量名 | 说明 |
|---|---|
BG_TOKEN | 访问令牌 |
BROWSER_TOKEN | 云服务 API Token |
CHROME_PATH | Chrome 可执行文件路径 |
配置加载机制
配置文件通过 src/server/config/loader.ts 模块加载,支持热重载。启动时使用 --config 参数指定配置文件路径。
# 指定配置文件
browser-gateway serve --config /path/to/gateway.yml
# 开发环境
browser-gateway serve --config gateway.dev.yml
配置验证
启动时会自动验证配置格式,错误时输出详细的验证信息并终止启动。也可通过 API 验证配置而不保存:
curl -X POST http://localhost:9500/v1/config/validate \
-H "Content-Type: application/yaml" \
-d "$(cat gateway.yml)"
命令行参数
| 参数 | 说明 |
|---|---|
--config <path> | 指定配置文件路径 |
serve | 以服务器模式启动 |
check | 测试提供商连接 |
version | 显示版本信息 |
help | 显示帮助信息 |
# 完整启动命令
browser-gateway serve --config gateway.yml
# 测试配置
browser-gateway check
# 查看版本
browser-gateway version
完整配置示例
server:
host: "0.0.0.0"
port: 9500
http:
enabled: true
cors:
origin: "https://your-app.com"
credentials: true
prefix: "/v1"
providers:
- id: "local-chrome"
type: "launch"
url: "http://localhost:9222"
priority: 0
maxConcurrent: 5
labels: ["local"]
- id: "playwright-server"
type: "connect"
url: "ws://localhost:3000"
priority: 1
maxConcurrent: 10
labels: ["server"]
- id: "cloud-service"
type: "ws"
url: "wss://provider.com?token=${BROWSER_TOKEN}"
priority: 2
maxConcurrent: 50
labels: ["cloud"]
pool:
maxConcurrent: 20
sessionTtl: 300
idleTimeout: 60
auth:
enabled: true
token: "${BG_TOKEN}"
security:
allowedIps: []
rateLimit:
enabled: true
maxRequests: 1000
windowMs: 60000
logging:
level: "info"
format: "json"
常见配置问题
提供商连接失败
- 确认 WebSocket URL 可访问
- 检查防火墙是否放行对应端口
- 验证 API Token 是否有效
会话池耗尽
当并发请求超过 pool.maxConcurrent 时,新请求会排队等待。可以通过以下方式解决:
- 提高
pool.maxConcurrent值 - 为不同业务配置独立的提供商
- 使用标签(labels)进行请求路由
认证问题
启用认证后,所有 API 请求需要在请求头中携带 Token:
curl -H "Authorization: Bearer ${BG_TOKEN}" \
http://localhost:9500/v1/status来源:https://github.com/browser-gateway/browser-gateway / 项目说明书
系统架构
browser-gateway 是一个专为 AI Agent 设计的高可靠、可扩展的浏览器基础设施网关。它通过统一的 WebSocket 接口将各种浏览器提供方(Provider)进行抽象,为上层应用提供可靠的浏览器操作能力,同时支持 REST API、MCP Server 等多种接入方式。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
整体架构概览
browser-gateway 采用分层架构设计,从上到下分为四层:
graph TD
subgraph 接入层
REST[REST API<br/>v0.1.5+]
MCP[MCP Server<br/>v0.1.5+]
WS[WebSocket<br/>核心接口]
CDP[CDP Auto-Discovery<br/>v0.1.8+]
end
subgraph 路由层
Router[请求路由器]
Pool[会话池<br/>Session Pool v0.2.0+]
LB[负载均衡器]
end
subgraph 核心层
Gateway[Gateway 核心]
Registry[Provider 注册表]
Session[会话管理]
Failover[故障转移]
end
subgraph 供给层
P1[Provider 1<br/>Playwright]
P2[Provider 2<br/>Cloud Service]
P3[Provider 3<br/>Puppeteer]
Chrome[本地 Chrome<br/>Auto-detect]
end
REST --> Router
MCP --> Router
WS --> Router
CDP --> Router
Router --> LB
LB --> Pool
Pool --> Gateway
Gateway --> Registry
Registry --> P1
Registry --> P2
Registry --> P3
Registry --> Chrome核心组件
Gateway 核心
Gateway 是系统的核心调度引擎,负责管理所有浏览器会话的生命周期。
职责范围:
- 接收并解析来自路由层的请求
- 管理浏览器会话的创建、复用和销毁
- 处理会话持久化(v0.1.8+)
- 协调 Provider 之间的故障转移
核心入口位于 src/server/index.ts,通过 Hono 框架构建 HTTP 服务器,挂载 WebSocket 路由和 REST API 端点。
Provider 注册表
Provider 注册表(src/core/providers/registry.ts)管理所有已配置的浏览器供给方。
| 配置项 | 类型 | 说明 |
|---|---|---|
id | string | Provider 唯一标识符 |
type | string | 类型:playwright / puppeteer / cloud |
wsUrl | string | WebSocket 连接地址 |
priority | number | 优先级(数值越小优先级越高) |
maxConcurrent | number | 最大并发连接数 |
healthy | boolean | 健康状态 |
Provider 类型支持:
graph LR
subgraph 支持的 Provider
PW[Playwright Server]
PP[Puppeteer]
CS[Cloud Browser]
LC[本地 Chrome]
end
PW --> ws1[ws://server:3000]
PP --> ws2[wss://provider.com]
CS --> ws3[Any WebSocket URL]
LC --> ws4[自动检测]会话管理
会话管理模块(src/core/proxy/session.ts)负责维护客户端与浏览器实例之间的会话状态。
关键特性:
- 会话持久化:断开连接后重新连接可恢复同一浏览器实例 资料来源:src/core/proxy/session.ts
- Cookie、localStorage、页面状态自动保留
- 可配置的 TTL(默认 5 分钟)
- 通过
?sessionId=查询参数重连 资料来源:社区 v0.1.8
sequenceDiagram
participant Client
participant Gateway
participant Browser
Client->>Gateway: 连接请求
Gateway->>Browser: 创建/分配会话
Browser-->>Gateway: 会话 ID
Gateway-->>Client: 连接成功 + sessionId
Client->>Gateway: 断开连接
Note over Gateway: 保持 Browser 存活 (TTL)
Client->>Gateway: 重连 ?sessionId=xxx
Gateway->>Browser: 恢复会话
Browser-->>Gateway: 状态恢复
Gateway-->>Client: 会话已恢复请求处理流程
REST API 请求流程
v0.2.0 引入的 REST API 提供了简化的 HTTP 接口,无需直接管理 WebSocket 连接。
graph LR
subgraph HTTP 请求
POST[POST /v1/screenshot]
CONTENT[POST /v1/content]
SCRAPE[POST /v1/scrape]
end
subgraph 处理流程
Validate[参数验证]
Route[路由选择]
Pool[获取会话]
Execute[执行操作]
Return[返回结果]
end
POST --> Validate
CONTENT --> Validate
SCRAPE --> Validate
Validate --> Route
Route --> Pool
Pool --> Execute
Execute --> ReturnREST 端点列表:
| 端点 | 方法 | 功能 |
|---|---|---|
/v1/screenshot | POST | 截取页面截图 |
/v1/content | POST | 提取页面内容(markdown/text/html/readability) |
/v1/scrape | POST | 使用 CSS 选择器提取数据 |
/v1/status | GET | 网关状态和 Provider 信息 |
/v1/sessions | GET | 活跃会话列表 |
/v1/providers | GET/POST | Provider 管理 |
内容提取流程
内容提取是核心功能之一,支持多种格式:
graph TD
subgraph extractWithDefuddle
RawHTML[原始 HTML]
Parse[解析内容]
Markdown{需要 Markdown?}
Readability{需要 Readability?}
RawHTML --> Parse
Parse --> Markdown
Markdown -->|是| MD[转换为 Markdown]
Markdown -->|否| Readability
Readability -->|是| RA[Readability 提取]
Readability -->|否| Meta[基础元数据]
MD --> OutputMD[输出内容]
RA --> OutputRA[输出内容]
Meta --> OutputMeta[元数据]
end会话池机制
v0.2.0 引入的会话池(Session Pool)是架构的重大升级,实现了浏览器连接的复用。
核心特性:
| 特性 | 说明 |
|---|---|
| 连接复用 | 多个 HTTP 请求共享同一浏览器实例 |
| 自动路由 | 请求自动分配到可用的会话 |
| 自动重试 | 失败请求自动使用新会话重试 |
| 负载均衡 | 基于优先级的请求分发 |
graph TD
subgraph 请求入口
Req1[HTTP 请求 1]
Req2[HTTP 请求 2]
Req3[HTTP 请求 3]
end
subgraph Session Pool
S1[会话 1]
S2[会话 2]
S3[会话 3]
end
subgraph Browser Instances
B1[浏览器 1]
B2[浏览器 2]
B3[浏览器 3]
end
Req1 --> PoolReq1[获取可用会话]
Req2 --> PoolReq2[获取可用会话]
Req3 --> PoolReq3[获取可用会话]
PoolReq1 --> S1
PoolReq2 --> S2
PoolReq3 --> S1
S1 --> B1
S2 --> B2
S3 --> B3MCP Server 架构
v0.1.5 引入的 MCP Server 为 AI Agent 提供原生的浏览器工具支持。
8 个核心工具:
| 工具名 | 功能 |
|---|---|
navigate | 导航到指定 URL |
snapshot | 获取页面快照 |
screenshot | 截取屏幕截图 |
viewport | 设置视口大小 |
interact | 与页面元素交互 |
evaluate | 执行 JavaScript |
close | 关闭标签页 |
status | 获取浏览器状态 |
graph TD
subgraph MCP Client
Claude[Claude Code]
Cursor[Cursor]
Other[其他 MCP 客户端]
end
subgraph MCP Server
Handler[请求处理器]
Tools[8 个浏览器工具]
CDP[CDP 协议转换]
end
subgraph Browser
Chrome[Chrome/Chromium]
end
Claude --> Handler
Cursor --> Handler
Other --> Handler
Handler --> Tools
Tools --> CDP
CDP --> ChromeCDP 自动发现
v0.1.8 引入的 CDP 自动发现端点简化了第三方库的集成。
支持的库:
- browser-use
- Playwright
- Stagehand
使用方式:直接传入 http://localhost:9500 而非完整的 WebSocket URL。
Web Dashboard
内置的 Web Dashboard 提供可视化的管理界面。
| 页面 | 功能 |
|---|---|
| Overview | 网关健康状态、活跃会话数、Provider 状态 |
| Providers | 添加、编辑、删除、测试 Provider |
| Sessions | 实时活跃连接列表 |
| Config | 编辑 gateway.yml 配置 |
认证机制
Dashboard 支持可选的 token 认证:
- 环境变量:
BG_TOKEN - 认证方式:安全的 HttpOnly Cookie
- 适用场景:生产环境部署
配置架构
系统通过 YAML 文件配置,支持多 Provider 故障转移:
providers:
- id: local-playwright
type: playwright
wsUrl: ws://localhost:3000
priority: 1
maxConcurrent: 5
- id: cloud-provider
type: cloud
wsUrl: wss://provider.com?token=xxx
priority: 2
maxConcurrent: 10
session:
ttl: 300 # 5 分钟
pool:
maxSessions: 20
idleTimeout: 60
依赖关系图
graph TD
Server[src/server/index.ts]
Gateway[src/core/gateway.ts]
Registry[src/core/providers/registry.ts]
Session[src/core/proxy/session.ts]
REST[src/server/rest/*.ts]
WS[src/server/websocket.ts]
MCP[src/mcp/server.ts]
Server --> Gateway
Server --> WS
Server --> REST
Server --> MCP
Gateway --> Registry
Gateway --> Session
REST --> Gateway
WS --> Gateway
MCP --> Gateway技术栈
| 层级 | 技术选型 |
|---|---|
| 运行时 | Node.js (ESM) |
| Web 框架 | Hono |
| WebSocket | ws / hono/ws |
| HTTP 客户端 | ky |
| 内容提取 | @mozilla/readability, turndown |
| MCP | @modelcontextprotocol/sdk |
| Dashboard | Next.js |
| UI 组件 | base-ui/react |
版本演进
| 版本 | 重大特性 |
|---|---|
| v0.1.5 | MCP Server、零配置启动 |
| v0.1.8 | 会话持久化、CDP 自动发现 |
| v0.2.0 | REST API、Session Pool、Auto-Discovery |
扩展阅读
来源:https://github.com/browser-gateway/browser-gateway / 项目说明书
WebSocket 代理机制
Browser Gateway 的核心功能是作为浏览器实例的 WebSocket 代理网关。它为 AI 代理和应用程序提供可靠的、可扩展的浏览器基础设施,通过统一的 WebSocket 端点将客户端请求路由到远程浏览器服务提供商。
继续阅读本节完整说明和来源证据。
概述
Browser Gateway 的核心功能是作为浏览器实例的 WebSocket 代理网关。它为 AI 代理和应用程序提供可靠的、可扩展的浏览器基础设施,通过统一的 WebSocket 端点将客户端请求路由到远程浏览器服务提供商。
核心能力:
- 协议无关:支持 Playwright、Puppeteer、Chrome DevTools Protocol (CDP) 等任何 WebSocket 协议
- 多提供商路由:根据优先级和可用性自动选择最优浏览器提供商
- 会话持久化:断开重连后保持 Cookie、localStorage 和页面状态
- 故障转移:主提供商不可用时自动切换到备用提供商
资料来源:package.json:1-15
资料来源:package.json:1-15
会话池与状态持久化
会话池(Session Pool)与状态持久化是 browser-gateway 实现可靠、可扩展浏览器基础设施的核心模块。它们共同解决了两个关键问题:如何在多个请求间高效复用浏览器实例,以及如何在断开连接后恢复用户的浏览状态。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
会话池(Session Pool)与状态持久化是 browser-gateway 实现可靠、可扩展浏览器基础设施的核心模块。它们共同解决了两个关键问题:如何在多个请求间高效复用浏览器实例,以及如何在断开连接后恢复用户的浏览状态。
从 v0.1.8 引入的会话持久化机制,到 v0.2.0 完善后的会话池架构,这一系统允许用户断开连接后重新连接到同一个浏览器实例,保持 Cookie、localStorage、页面状态等数据不丢失。通过 ?sessionId= 查询参数即可指定会话进行重连,默认 TTL(生存时间)为 5 分钟。
架构设计
核心组件关系
graph TD
A[客户端请求] --> B{请求类型}
B -->|REST API| C[REST Executor]
B -->|MCP| D[MCP Tools]
B -->|WebSocket| E[WebSocket Handler]
C --> F[Session Pool]
D --> F
E --> F
F --> G{可用会话?}
G -->|是| H[复用会话]
G -->|否| I[创建新会话]
H --> J[状态恢复]
I --> K[启动浏览器]
K --> J
J --> L[执行操作]
L --> M[返回结果]
M --> N[会话释放回池]模块职责
| 模块 | 路径 | 职责 |
|---|---|---|
| session-pool.ts | src/core/pool/ | 会话池的核心实现,管理会话的创建、分配、回收和销毁 |
| index.ts | src/core/pool/ | 会话池的导出和公共接口定义 |
| types.ts | src/core/pool/ | 会话相关的类型定义和接口 |
| executor.ts | src/server/rest/ | REST API 请求的执行器,封装页面操作逻辑 |
会话生命周期
会话状态流转
stateDiagram-v2
[*] --> Created: 创建会话
Created --> Active: 分配给客户端
Active --> Idle: 操作完成
Idle --> Active: 新请求到达
Active --> Disconnected: 客户端断开
Disconnected --> Active: 客户端重连
Disconnected --> Expired: TTL 超时
Expired --> [*]: 清理资源
Idle --> Expired: TTL 超时会话池管理策略
会话池采用以下策略管理会话资源:
- 会话分配:当请求到达时,池会检查是否有空闲会话可用
- 状态保持:断开的会话在 TTL 过期前保留所有状态数据
- 自动清理:会话过期后自动释放浏览器实例和关联资源
- 重连机制:客户端可通过
sessionId参数恢复到之前的会话
状态持久化机制
支持持久化的状态类型
| 状态类型 | 说明 | 持久化方式 |
|---|---|---|
| Cookie | 网站认证和偏好设置 | 浏览器原生持久化 |
| localStorage | 前端应用数据 | 浏览器原生持久化 |
| sessionStorage | 会话级存储 | 浏览器原生持久化 |
| 页面状态 | DOM 树、滚动位置、表单数据 | 通过 CDP 协议恢复 |
| 浏览器上下文 | 浏览器实例的完整上下文 | 内存保留至 TTL |
状态恢复流程
sequenceDiagram
participant Client as 客户端
participant Gateway as Gateway
participant Pool as Session Pool
participant Browser as 浏览器实例
Client->>Gateway: 断开连接 (sessionId=xxx)
Gateway->>Pool: 将会话标记为断开
Pool->>Browser: 保持浏览器运行
Note over Pool: TTL 倒计时开始 (默认5分钟)
Client->>Gateway: 重连请求 ?sessionId=xxx
Gateway->>Pool: 根据 sessionId 查找会话
Pool->>Browser: 恢复 CDP 连接
Browser-->>Pool: 状态已恢复
Pool-->>Gateway: 会话可用
Gateway-->>Client: 连接成功REST API 执行器集成
Executor 工作机制
REST API 执行器(executor.ts)是会话池与 REST 接口之间的桥梁。它接收 HTTP 请求中的参数,分配或复用会话,执行页面操作,最后返回结果。
graph LR
A[HTTP 请求] --> B[参数解析]
B --> C[会话获取]
C --> D[页面操作]
D --> E[结果提取]
E --> F[响应返回]
F --> G[会话释放]核心操作支持
#### 内容提取
在 content.ts 和 scrape.ts 中,内容提取功能与会话池紧密集成:
- HTML 提取:直接获取页面完整 HTML 内容
- 纯文本提取:通过
document.body.innerText获取文本 - Markdown 转换:使用 defuddle 库将 HTML 转为 Markdown
- 可读性优化:提取文章内容,移除广告和导航
资料来源:src/server/rest/content.ts:17-25
if (body.formats.includes("text")) {
content.text = await page.evaluate("document.body.innerText") as string;
}
#### 页面元数据
所有格式请求都会收集标准元数据:
| 元数据字段 | 来源 |
|---|---|
| title | document.title |
| description | meta[name="description"] |
| author | meta[name="author"] |
| language | documentElement.lang |
| published | 文章发布日期(如有) |
| image | og:image(如有) |
| favicon | 网站图标 |
| wordCount | 单词计数 |
#### 链接提取
const links = await page.evaluate(`
Array.from(document.querySelectorAll("a[href]"))
.map(a => ({ url: a.href, text: (a.textContent || "").trim() }))
.filter(l => l.url && l.text)
`) as Array<{ url: string; text: string }>;
#### 屏幕截图
截图功能支持 JPEG 格式,质量设置为 80:
const buf = await page.screenshot({
fullPage: false,
type: "jpeg",
quality: 80,
});
output.screenshot = buf.toString("base64");
资料来源:src/server/rest/scrape.ts:52-58
MCP 工具集成
MCP 中的会话管理
MCP 服务器同样利用会话池来管理浏览器资源。工具定义中的 sessionId 参数允许客户端指定要使用的会话。
资料来源:src/server/mcp/tools.ts:1-20
server.registerTool("browser_interact", {
inputSchema: z.object({
action: z.enum(["click", "type", "select", "press", "scroll"]),
sessionId: z.string().optional().describe("Session ID"),
// ... 其他参数
}),
}, async ({ action, sessionId, ... }) => {
const session = await getOrCreateSession(sessionId);
if (!session) return err("No active session. Call browser_navigate first.");
// 执行操作
});
交互操作类型
| 操作 | 说明 | 参数 |
|---|---|---|
| click | 点击元素 | selector(引用或 CSS 选择器) |
| type | 输入文本 | selector, text, clear |
| select | 选择下拉选项 | selector, value |
| press | 按键操作 | key(Enter, Tab, Escape 等) |
| scroll | 滚动页面 | direction(up/down) |
配置选项
YAML 配置
在 gateway.yml 中可以配置会话池参数:
| 配置项 | 默认值 | 说明 |
|---|---|---|
| session.ttl | 300(5分钟) | 会话生存时间(秒) |
| pool.maxSessions | - | 最大并发会话数 |
| pool.idleTimeout | - | 空闲会话超时时间 |
环境变量
| 变量 | 说明 |
|---|---|
| BG_SESSION_TTL | 覆盖默认 TTL |
| BG_TOKEN | 仪表板认证令牌 |
使用示例
断开后重连
- 首次连接并执行操作:
# 发起请求,系统自动分配 sessionId
curl -X POST http://localhost:9500/v1/content \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
- 断开连接(不关闭浏览器):
# 保持浏览器运行,sessionId 在 TTL 内有效
- 使用 sessionId 重连:
# 通过 ?sessionId=xxx 参数重连
curl -X POST http://localhost:9500/v1/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/page2", "sessionId": "xxx"}'
会话状态保持场景
| 场景 | 行为 |
|---|---|
| 用户登录后断开 | Cookie 和 session 保持 |
| 填写长表单断开 | 表单数据在 localStorage 中保留 |
| 滚动浏览长列表断开 | 页面状态和滚动位置恢复 |
| 多标签操作断开 | 所有标签状态在 TTL 内可恢复 |
性能考量
资源管理
- 内存占用:每个活跃会话占用浏览器实例资源
- 连接复用:合理使用 sessionId 可减少浏览器启动开销
- TTL 设置:过长的 TTL 会占用过多资源,过短则影响用户体验
最佳实践
- 批量操作:将相关操作合并到同一会话中
- 及时断开:完成操作后主动断开以释放资源
- 合理 TTL:根据业务场景调整 TTL 长度
- 错误处理:实现重试逻辑应对会话过期
API 端点与会话关联
| 端点 | 方法 | 会话行为 |
|---|---|---|
| /v1/screenshot | POST | 分配/复用会话 |
| /v1/content | POST | 分配/复用会话 |
| /v1/scrape | POST | 分配/复用会话 |
| /v1/sessions | GET | 列出所有活跃会话 |
| /v1/providers | GET/POST | 管理浏览器提供者 |
故障排除
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 会话无法恢复 | TTL 已过期 | 重新发起请求创建新会话 |
| sessionId 无效 | 会话不存在 | 检查 sessionId 拼写或创建新会话 |
| 状态丢失 | 浏览器崩溃 | 重新连接,系统自动分配新会话 |
监控会话状态
通过 /v1/sessions 端点可以监控所有活跃会话:
curl http://localhost:9500/v1/sessions
返回当前活跃的会话列表,包括会话 ID、提供者信息、持续时间和消息计数。
REST API 详解
REST API 是 browser-gateway 在 v0.2.0 版本中引入的核心功能,旨在将网关转变为一个完整的浏览器操作 API。通过简洁的 HTTP POST 请求,用户可以直接获取截图、内容提取或结构化数据,无需管理 WebSocket 连接。 资料来源:README.md
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
REST API 是 browser-gateway 在 v0.2.0 版本中引入的核心功能,旨在将网关转变为一个完整的浏览器操作 API。通过简洁的 HTTP POST 请求,用户可以直接获取截图、内容提取或结构化数据,无需管理 WebSocket 连接。 资料来源:README.md
REST API 的主要特点包括:
- 会话池化(Session Pool):浏览器连接在多个请求之间复用,类似于数据库连接池
- 自动重试(Auto-Retry):失败的请求会自动使用新的浏览器页面重试
- 协议无关(Protocol Agnostic):支持 Playwright、Puppeteer 等任何 WebSocket 协议
- 零配置启动:auto-detect Chrome,启动后即可使用
核心端点
REST API 提供以下核心端点:
| 端点 | 方法 | 描述 |
|---|---|---|
/v1/screenshot | POST | 捕获任意页面的屏幕截图(PNG 或 JPEG) |
/v1/content | POST | 以 markdown、text、HTML 或 cleaned article 格式提取页面内容 |
/v1/scrape | POST | 通过 CSS 选择器提取数据或获取全页内容 |
/v1/status | GET | 网关健康状态、provider 状态和连接池状态 |
/v1/sessions | GET | 活跃会话列表 |
/v1/providers | GET/POST | 列出或添加 providers |
/v1/providers/:id | PUT/DELETE | 更新或删除 provider |
/v1/providers/:id/test | POST | 测试 provider 连接性 |
/v1/config | GET/PUT | 读取或保存配置 |
/v1/config/validate | POST | 验证 YAML 配置(不保存) |
资料来源:README.md
架构设计
请求处理流程
graph TD
A[HTTP POST 请求] --> B{认证检查}
B -->|有 token| C[验证 Bearer Token]
B -->|无 token| D[通过]
C -->|无效| E[返回 401 Unauthorized]
C -->|有效| D
D --> F[路由到对应端点处理器]
F --> G[从会话池获取浏览器页面]
G --> H{Provider 可用?}
H -->|否| I[进入冷静期或选择其他 provider]
H -->|是| J[执行页面操作]
J --> K{操作成功?}
K -->|是| L[返回结果]
K -->|否| M[重试?]
M -->|是| G
M -->|否| N[返回错误]
L --> O[释放或保留会话到池中]
N --> O会话池机制
会话池(Session Pool)是 REST API 实现连接复用的核心组件。每个会话代表一个活跃的浏览器连接,包含以下元数据:
| 字段 | 类型 | 描述 |
|---|---|---|
| id | string | 唯一会话标识符 |
| providerId | string | 关联的 provider ID |
| connectedAt | number | 连接建立时间戳 |
| lastActivity | number | 最后活动时间戳 |
| messageCount | number | 消息计数 |
重试机制
REST API 内置智能重试机制,通过 executor.ts 实现。系统区分可重试和不可重试的错误类型:
graph TD
A[请求失败] --> B{错误类型检查}
B -->|ERR_NAME_NOT_RESOLVED| C[不可重试]
B -->|ERR_INVALID_URL| C
B -->|ERR_CERT_*| C
B -->|ERR_SSL_*| C
B -->|Protocol error| C
B -->|其他错误| D[可重试]
C --> E[返回错误]
D --> F{重试次数 < max?}
F -->|是| G[等待后重试]
F -->|否| E
G --> H[获取新页面]
H --> I{成功?}
I -->|是| J[返回结果]
I -->|否| D不可重试的错误包括:
ERR_NAME_NOT_RESOLVED- DNS 解析失败ERR_INVALID_URL- 无效的 URL 格式ERR_CERT_*/ERR_SSL_*- SSL 证书错误Protocol error- 协议错误
资料来源:src/server/rest/executor.ts:22-28
`/v1/screenshot` 端点
功能说明
截图端点用于捕获任意 URL 的页面截图,支持配置视口大小、图片格式和质量参数。
请求参数
| 参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| url | string | 是 | - | 目标页面 URL |
| viewport | object | 否 | {width: 1280, height: 720} | 视口尺寸 |
| fullPage | boolean | 否 | false | 是否截取整页 |
| type | string | 否 | png | 图片格式:png 或 jpeg |
| quality | number | 否 | 80 | JPEG 图片质量 (0-100) |
| timeout | number | 否 | 30000 | 超时时间(毫秒) |
| waitUntil | string | 否 | load | 等待策略 |
| waitForSelector | string | 否 | - | 等待特定元素出现 |
| waitForTimeout | number | 否 | - | 等待时间(毫秒) |
| headers | object | 否 | - | 自定义请求头 |
| userAgent | string | 否 | - | 自定义 User-Agent |
| retries | number | 否 | 2 | 重试次数 |
响应格式
{
"success": true,
"data": {
"url": "https://example.com",
"statusCode": 200,
"screenshot": "base64_encoded_image_data",
"metadata": {
"width": 1280,
"height": 720
}
},
"timings": {
"total": 1523,
"navigation": 1200,
"action": 323
}
}
资料来源:src/server/rest/screenshot.ts
`/v1/content` 端点
功能说明
内容提取端点用于获取页面的各种文本格式,支持 markdown、纯文本、HTML 原文和可读性优化内容。
请求参数
| 参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| url | string | 是 | - | 目标页面 URL |
| formats | string[] | 是 | - | 输出格式数组 |
| viewport | object | 否 | {width: 1280, height: 720} | 视口尺寸 |
| timeout | number | 否 | 30000 | 超时时间(毫秒) |
| waitUntil | string | 否 | load | 等待策略 |
| waitForSelector | string | 否 | - | 等待特定元素出现 |
| headers | object | 否 | - | 自定义请求头 |
| userAgent | string | 否 | - | 自定义 User-Agent |
| retries | number | 否 | 2 | 重试次数 |
支持的格式
| 格式 | 描述 | 附加元数据 |
|---|---|---|
| markdown | 转换为 Markdown 格式 | title, description, author, wordCount, site |
| text | 纯文本提取 | title, description, author |
| html | 原始 HTML 内容 | - |
| readability | 可读性优化内容 | title, description, author, published, language, image, favicon, wordCount, site |
响应格式
{
"success": true,
"data": {
"url": "https://example.com",
"statusCode": 200,
"content": {
"markdown": "# 页面标题\n\n这是页面内容...",
"text": "页面标题\n\n这是页面内容...",
"readability": "优化后的可读内容..."
},
"metadata": {
"title": "Example Domain",
"description": "页面描述",
"author": "作者名",
"wordCount": 1234,
"site": "example.com"
},
"links": [
{"url": "https://example.com/about", "text": "关于我们"}
]
},
"timings": {
"total": 2100,
"navigation": 1500,
"action": 600
}
}
内部处理流程
当请求包含 markdown 或 readability 格式时,系统会调用 extractWithDefuddle 函数进行处理:
- 获取原始 HTML 内容
- 根据格式参数决定是否转换为 Markdown
- 提取元数据(标题、描述、作者等)
- 如果同时请求 markdown 和 readability,优先使用 readability 的元数据
资料来源:src/server/rest/content.ts
`/v1/scrape` 端点
功能说明
数据抓取端点提供更灵活的数据提取能力,支持通过 CSS 选择器精准提取页面元素,或获取完整页面内容。
请求参数
| 参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| url | string | 是 | - | 目标页面 URL |
| selectors | Selector[] | 否 | - | CSS 选择器数组 |
| formats | string[] | 否 | - | 完整页面格式 |
| screenshot | boolean | 否 | false | 是否同时返回截图 |
| viewport | object | 否 | {width: 1280, height: 720} | 视口尺寸 |
| timeout | number | 否 | 30000 | 超时时间(毫秒) |
| waitUntil | string | 否 | load | 等待策略 |
| waitForSelector | string | 否 | - | 等待特定元素出现 |
| headers | object | 否 | - | 自定义请求头 |
| userAgent | string | 否 | - | 自定义 User-Agent |
| retries | number | 否 | 2 | 重试次数 |
Selector 对象
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | string | 是 | 数据字段名称 |
| selector | string | 是 | CSS 选择器 |
| attribute | string | 否 | 提取的属性(如 href、src) |
formats 支持的格式
与 /v1/content 端点相同,支持:markdown、text、html、readability
响应格式
{
"success": true,
"data": {
"url": "https://example.com",
"statusCode": 200,
"data": {
"title": "页面标题",
"links": ["https://example.com/about"]
},
"content": {
"markdown": "# 页面内容..."
},
"screenshot": "base64_encoded_image",
"metadata": {
"title": "Example Domain",
"description": "页面描述"
}
},
"timings": {
"total": 1800,
"navigation": 1300,
"action": 500
}
}
业务规则
- 必填校验:必须提供
selectors或formats(或两者都提供) - Markdown/Readability 处理:当请求包含这些格式时,使用 defuddle 库进行处理
- 元数据合并:如果同时请求 readability 和 markdown,元数据从 readability 结果获取
资料来源:src/server/rest/schemas.ts:40-43
请求选项详解
等待策略(waitUntil)
| 值 | 描述 |
|---|---|
| load | 默认值,等待 load 事件 |
| domcontentloaded | 等待 DOMContentLoaded 事件 |
| networkidle | 等待网络空闲 |
| commit | 页面开始响应即可 |
视口配置
{
"viewport": {
"width": 1920,
"height": 1080
}
}
默认视口为 1280x720,适用于大多数场景。
认证机制
当设置 BG_TOKEN 环境变量时,所有 /v1/* 端点都需要认证:
| 客户端类型 | 认证方式 |
|---|---|
| WebSocket 客户端 | ?token=<token> 查询参数 |
| API 客户端 | Authorization: Bearer <token> 请求头 |
| 仪表板 | 登录表单,设置 HttpOnly cookie |
注意:/health 端点始终公开可用,无需认证。
资料来源:README.md
使用示例
截图示例
# 基本截图
curl -X POST http://localhost:9500/v1/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}' --output screenshot.png
# 整页截图
curl -X POST http://localhost:9500/v1/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "fullPage": true, "type": "jpeg", "quality": 90}' \
--output screenshot.jpg
# 自定义视口
curl -X POST http://localhost:9500/v1/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "viewport": {"width": 1920, "height": 1080}}'
内容提取示例
# 提取 Markdown
curl -X POST http://localhost:9500/v1/content \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "formats": ["markdown"]}'
# 同时提取多种格式
curl -X POST http://localhost:9500/v1/content \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "formats": ["markdown", "text", "html"]}'
# 可读性优化内容
curl -X POST http://localhost:9500/v1/content \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "formats": ["readability"]}'
数据抓取示例
# 使用 CSS 选择器提取数据
curl -X POST http://localhost:9500/v1/scrape \
-H "Content-Type: application/json" \
-d '{
"url": "https://news.ycombinator.com",
"selectors": [
{"name": "titles", "selector": ".titleline > a"},
{"name": "scores", "selector": ".score"}
]
}'
# 提取带截图
curl -X POST http://localhost:9500/v1/scrape \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"selectors": [{"name": "title", "selector": "h1"}],
"screenshot": true
}'
# 结合页面格式和选择器
curl -X POST http://localhost:9500/v1/scrape \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"selectors": [{"name": "price", "selector": ".price"}],
"formats": ["markdown"]
}'
性能优化
会话池配置
会话池允许配置每个 provider 的最大并发数:
providers:
primary:
url: wss://provider.example.com
limits:
maxConcurrent: 5
priority: 1
建议
- 合理设置超时:避免长时间等待无响应页面
- 使用选择器而非全文:只请求需要的数据,减少传输量
- 批量处理:多个 URL 请求可并行发送
- 选择合适的等待策略:不需要完整加载时使用
domcontentloaded
错误处理
常见错误响应
| HTTP 状态码 | 错误信息 | 原因 |
|---|---|---|
| 400 | Bad Request | 请求参数验证失败 |
| 401 | Unauthorized | 缺少或无效的认证 token |
| 404 | Not Found | 资源不存在 |
| 500 | Internal Server Error | 服务器内部错误 |
| 503 | Service Unavailable | 所有 provider 都不可用 |
错误响应格式
{
"success": false,
"error": "错误描述",
"code": "ERROR_CODE"
}
相关文档
资料来源:README.md
MCP 服务器
MCP 服务器是 browser-gateway 内置的 Model Context Protocol 实现,为 AI 智能体提供直接的浏览器访问能力。通过 MCP 协议,AI 智能体可以执行网页导航、内容提取、截图、交互等操作,无需额外安装 Playwright 或 Puppeteer 等浏览器自动化工具。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
MCP 服务器是 browser-gateway 内置的 Model Context Protocol 实现,为 AI 智能体提供直接的浏览器访问能力。通过 MCP 协议,AI 智能体可以执行网页导航、内容提取、截图、交互等操作,无需额外安装 Playwright 或 Puppeteer 等浏览器自动化工具。
graph TB
subgraph "MCP 客户端"
A[Claude Code]
B[Cursor]
C[其他 MCP 兼容客户端]
end
subgraph "browser-gateway MCP 服务器"
D[MCP Streamable HTTP]
E[工具注册表]
F[浏览器会话管理]
end
subgraph "浏览器层"
G[本地 Chrome]
H[远程 CDP 提供商]
end
A --> D
B --> D
C --> D
D --> E
E --> F
F --> G
F --> HMCP 服务器随 browser-gateway v0.1.5 引入,提供 8 种浏览器操作工具,支持零配置启动和并发会话管理。资料来源:package.json:4
核心功能
8 种浏览器工具
| 工具名称 | 功能描述 | 输入参数 |
|---|---|---|
navigate | 导航到指定 URL | url, waitUntil |
snapshot | 获取页面快照 | url |
screenshot | 截取页面截图 | url, fullPage |
viewport | 设置视口大小 | width, height |
interact | 执行页面交互 | selector, action, value |
evaluate | 执行 JavaScript | script |
close | 关闭当前页面 | 无 |
status | 获取浏览器状态 | 无 |
资料来源:docs/mcp.md
零配置启动
MCP 服务器默认自动检测本地 Chrome 安装,无需手动配置浏览器路径。首次使用工具时会自动启动浏览器实例。资料来源:src/server/mcp/local-chrome.ts
并发会话支持
每个 AI 智能体获得独立的浏览器实例,不同智能体之间不会产生冲突。MCP 服务器通过会话管理模块维护多个独立的浏览器连接。资料来源:src/server/mcp/sessions.ts
架构设计
组件结构
graph TD
A[MCP 服务器入口] --> B[server.ts - HTTP 端点]
B --> C[Streamable HTTP 处理]
C --> D[工具路由分发]
D --> E[tools.ts - 工具定义]
E --> E1[navigate]
E --> E2[snapshot]
E --> E3[screenshot]
E --> E4[viewport]
E --> E5[interact]
E --> E6[evaluate]
E --> E7[close]
E --> E8[status]
D --> F[sessions.ts - 会话管理]
F --> F1[会话创建]
F --> F2[会话复用]
F --> F3[会话清理]
D --> G[local-chrome.ts - Chrome 管理]
G --> G1[Chrome 检测]
G --> G2[进程启动]
G --> G3[CDP 连接]MCP 端点
MCP 服务器通过 HTTP Streamable 协议提供服务,端点位于 /mcp。请求格式遵循 Model Context Protocol 规范。资料来源:docs/mcp.md
启动方式
命令行启动
# 默认启动,自动检测本地 Chrome
browser-gateway mcp
# 指定 Chrome 路径
browser-gateway mcp --chrome-path /usr/bin/google-chrome
# 连接到现有浏览器
browser-gateway mcp --cdp-endpoint ws://localhost:9222
# 使用配置文件启动
browser-gateway mcp --config gateway.yml
Claude Code 配置
在 Claude Code 配置文件中添加 MCP 服务器:
{
"mcpServers": {
"browser-gateway": {
"command": "npx",
"args": ["browser-gateway", "mcp"]
}
}
}
Cursor 配置
在 Cursor 设置中添加 MCP 服务器:
{
"mcpServers": {
"browser-gateway": {
"command": "npx",
"args": ["browser-gateway", "mcp"]
}
}
}
资料来源:docs/mcp.md
工具详解
navigate - 页面导航
导航到指定 URL 并等待页面加载完成。
输入参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
url | string | 是 | 目标页面 URL |
waitUntil | string | 否 | 等待策略:load, domcontentloaded, networkidle |
返回结果:
{
"url": "https://example.com",
"title": "Example Domain",
"statusCode": 200
}
snapshot - 内容快照
获取页面的结构化快照,包含标题、描述、主要内容等元数据。
输入参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
url | string | 是 | 目标页面 URL |
返回结果:
{
"title": "Page Title",
"description": "Page description",
"content": "Main content text...",
"language": "en"
}
screenshot - 页面截图
截取当前页面或完整页面的截图。
输入参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
url | string | 是 | 目标页面 URL |
fullPage | boolean | 否 | 是否截取整页,默认 false |
返回结果:
{
"data": "base64 encoded image...",
"mimeType": "image/png"
}
interact - 页面交互
执行点击、输入、悬停等页面交互操作。
输入参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
selector | string | 是 | CSS 选择器 |
action | string | 是 | 操作类型:click, hover, type, select |
value | string | 否 | 操作值(用于 type 和 select) |
evaluate - JavaScript 执行
在页面上下文中执行任意 JavaScript 代码。
输入参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
script | string | 是 | 要执行的 JavaScript 代码 |
viewport - 视口设置
设置浏览器视口的宽度和高度。
输入参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
width | number | 是 | 视口宽度(像素) |
height | number | 是 | 视口高度(像素) |
status - 状态查询
获取当前浏览器会话的状态信息。
返回结果:
{
"sessionId": "abc123",
"url": "https://example.com",
"title": "Example Domain",
"viewport": {
"width": 1920,
"height": 1080
}
}
close - 关闭页面
关闭当前浏览器页面,释放相关资源。
本地 Chrome 检测
MCP 服务器实现了智能的 Chrome 检测机制:
graph TD
A[启动 MCP 服务器] --> B{检测 CHROME_PATH 环境变量}
B -->|已设置| C[使用指定路径]
B -->|未设置| D{Windows}
D -->|是| E[检查常见安装路径]
D -->|否| F{macOS}
F -->|是| E
F -->|否| G[Linux AppImage/Flatpak]
E --> H[验证 Chrome 可执行]
G --> H
H -->|有效| I[启动 Chrome]
H -->|无效| J[返回错误]检测顺序:
CHROME_PATH环境变量- Windows:
C:\Program Files\Google\Chrome\Application\chrome.exe - macOS:
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome - Linux:
/usr/bin/google-chrome,/usr/bin/chromium-browser
资料来源:src/server/mcp/local-chrome.ts
会话管理
会话生命周期
graph LR
A[请求到达] --> B{查找现有会话}
B -->|存在| C[复用会话]
B -->|不存在| D[创建新会话]
C --> E[执行工具]
D --> E
E --> F{会话空闲超时}
F -->|超时| G[清理会话]
F -->|活跃| H[保留会话]会话特性
- 会话复用:相同客户端的后续请求复用已有会话
- TTL 管理:会话空闲时自动清理,默认为 5 分钟
- 独立状态:每个会话维护独立的 Cookie、LocalStorage 和页面状态
资料来源:src/server/mcp/sessions.ts
使用示例
完整使用流程
// 1. 启动 MCP 服务器
// browser-gateway mcp
// 2. AI 智能体发送导航请求
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "navigate",
"arguments": {
"url": "https://github.com"
}
}
}
// 3. 获取截图
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "screenshot",
"arguments": {
"url": "https://github.com",
"fullPage": false
}
}
}
// 4. 交互操作
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "interact",
"arguments": {
"selector": "a[href='/login']",
"action": "click"
}
}
}
与 Claude Code 配合
- 安装 browser-gateway:
npm install -g browser-gateway - 配置 Claude Code 的 MCP 设置
- 直接使用自然语言指令:
请访问 GitHub 并截取首页截图,然后告诉我页面上有哪些主要导航链接。
配置选项
命令行参数
| 参数 | 描述 | 默认值 |
|---|---|---|
--port | MCP 服务器监听端口 | 9500 |
--host | 服务器绑定地址 | localhost |
--chrome-path | Chrome 可执行文件路径 | 自动检测 |
--cdp-endpoint | 远程 CDP WebSocket 端点 | 无 |
--config | 配置文件路径 | gateway.yml |
--session-ttl | 会话存活时间(秒) | 300 |
环境变量
| 变量 | 描述 |
|---|---|
CHROME_PATH | Chrome 可执行文件路径 |
BG_PORT | Gateway 监听端口 |
BG_TOKEN | Dashboard 认证令牌 |
注意事项
- Chrome 安装:确保本地已安装 Google Chrome 或 Chromium
- 端口占用:默认端口 9500,确保无冲突
- 权限问题:Linux 上可能需要调整 Chrome 启动参数
- 资源限制:大量并发会话会消耗系统资源
相关文档
资料来源:docs/mcp.md
Webhook 通知系统
browser-gateway 的 Webhook 通知系统允许用户在提供商状态发生变化时接收实时通知。该系统采用事件驱动架构,当检测到提供商宕机、恢复、进入冷却期或队列超时时,自动向配置的 Webhook 端点发送 HTTP POST 请求。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
browser-gateway 的 Webhook 通知系统允许用户在提供商状态发生变化时接收实时通知。该系统采用事件驱动架构,当检测到提供商宕机、恢复、进入冷却期或队列超时时,自动向配置的 Webhook 端点发送 HTTP POST 请求。
资料来源:README.md:18
架构设计
系统组件
graph TD
GW[Gateway 核心]
WN[WebhookNotifier]
EH[事件处理器]
HR[HTTP 请求发送器]
RT[重试机制]
GW -->|发布事件| EH
EH -->|分发| WN
WN -->|构建负载| HR
HR -->|HTTP POST| Webhook
HR -->|失败| RT
RT -->|延迟重试| HR
subgraph "配置"
Webhook1[Webhook 配置 A]
Webhook2[Webhook 配置 B]
end
Webhook1 --> WN
Webhook2 --> WN事件流
sequenceDiagram
participant P as Provider
participant G as Gateway
participant W as WebhookNotifier
participant U as Webhook Endpoint
P->>G: Provider Down Event
G->>W: emit("provider.down", data)
W->>W: 构建 WebhookPayload
W->>U: POST /webhook_url
alt 请求成功
U-->>W: 200 OK
else 请求失败
U-->>W: 4xx/5xx Error
W->>W: 重试延迟: 1s, 5s, 15s
W->>U: 重试 POST
end事件类型
browser-gateway 的 Webhook 系统支持以下事件类型:
| 事件名称 | 触发条件 | Status 状态 |
|---|---|---|
provider.cooldown | 提供商进入冷却期(限流或临时不可用) | firing |
provider.down | 提供商完全不可用 | firing |
provider.up | 提供商从故障中恢复 | resolved |
shutdown.start | 网关开始关闭流程 | firing |
queue.timeout | 请求队列超时 | firing |
资料来源:src/core/notifications/webhooks.ts:37-56
Webhook 负载格式
每个 Webhook 请求都会发送以下 JSON 格式的负载:
{
"version": "1",
"timestamp": "2024-01-15T10:30:00.000Z",
"event": "provider.down",
"status": "firing",
"source": "browser-gateway",
"data": {
"providerId": "provider-a",
"reason": "connection_timeout",
"activeConnections": 5
}
}
字段说明
| 字段 | 类型 | 描述 |
|---|---|---|
version | string | Webhook 协议版本,当前为 "1" |
timestamp | string | ISO 8601 格式的事件时间戳 |
event | string | 事件类型名称 |
status | string | "firing" 表示问题进行中,"resolved" 表示问题已解决 |
source | string | 固定为 "browser-gateway" |
data | object | 事件相关的具体数据,不同事件类型包含不同字段 |
资料来源:src/core/notifications/webhooks.ts:14-25
重试机制
WebhookNotifier 实现了指数退避重试机制:
private retryDelays = [1000, 5000, 15000];
重试策略如下:
| 重试次数 | 延迟时间 |
|---|---|
| 第 1 次重试 | 1 秒 |
| 第 2 次重试 | 5 秒 |
| 第 3 次重试 | 15 秒 |
超过最大重试次数后,请求将被丢弃并记录错误日志。
资料来源:src/core/notifications/webhooks.ts:27
配置方式
配置结构
在 gateway.yml 中配置 Webhook:
webhooks:
- url: https://your-webhook-endpoint.com/notify
events:
- provider.down
- provider.up
- provider.cooldown
- queue.timeout
- url: https://slack-webhook.example.com/hooks/incoming
events:
- provider.down
配置参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
url | string | 是 | Webhook 端点 URL |
events | string[] | 否 | 要订阅的事件列表,默认接收所有事件 |
资料来源:gateway.dev.yml
核心实现
WebhookNotifier 类
export class WebhookNotifier {
private retryDelays = [1000, 5000, 15000];
constructor(
private webhooks: WebhookConfig[],
private logger: Logger
) {}
static fromGateway(gateway: Gateway, webhooks: WebhookConfig[], logger: Logger): WebhookNotifier {
const notifier = new WebhookNotifier(webhooks, logger);
gateway.on("provider.cooldown", (data) => {
notifier.send("provider.cooldown", "firing", data);
});
// ... 其他事件监听
return notifier;
}
async send(event: string, status: "firing" | "resolved", data: Record<string, unknown>): Promise<void> {
// 构建并发送 Webhook 负载
}
}
事件绑定
Webhooks 与 Gateway 核心通过事件系统集成:
graph LR
G[Gateway] -->|"on('provider.cooldown')"| WC[Webhooks 冷却]
G -->|"on('provider.down')"| WD[Webhooks 宕机]
G -->|"on('provider.up')"| WU[Webhooks 恢复]
G -->|"on('shutdown.start')"| WS[Webhooks 关闭]
G -->|"on('queue.timeout')"| WQ[Webhooks 超时]资料来源:src/core/notifications/webhooks.ts:29-56
使用场景
运维告警集成
将 Webhook 与 PagerDuty、Opsgenie 等告警系统集成:
webhooks:
- url: https://events.pagerduty.com/v2/enqueue
events:
- provider.down
- queue.timeout
Slack/Teams 通知
在 Slack 或 Microsoft Teams 频道中接收状态更新:
webhooks:
- url: https://hooks.slack.com/services/xxx/yyy/zzz
events:
- provider.down
- provider.up
自动化恢复
配合外部系统实现自动故障恢复:
webhooks:
- url: https://your-automation-service.com/webhook
events:
- provider.up
与 Gateway 生命周期集成
WebhookNotifier 在 Gateway 初始化时通过 fromGateway 静态方法创建,自动绑定所有事件监听器:
const notifier = WebhookNotifier.fromGateway(gateway, webhooks, logger);
这种设计确保了:
- 无状态通知:每个 Webhook 独立处理,无需维护连接状态
- 事件解耦:Gateway 核心与通知系统通过事件接口分离
- 可扩展性:可轻松添加新的事件类型或通知渠道
最佳实践
| 实践 | 说明 |
|---|---|
| 使用 HTTPS | 确保 Webhook URL 使用 HTTPS 协议 |
| 快速响应 | Webhook 处理服务应快速响应,避免阻塞 |
| 幂等性 | 接收端应支持幂等处理,应对重试场景 |
| 监控 | 监控 Webhook 端点的可用性和响应时间 |
| 过滤事件 | 仅订阅需要的事件,减少不必要的流量 |
限制与注意事项
- Webhook 通知是尽力而为的,不保证 100% 送达
- 重试机制仅在 3 次内有效,超过后请求将被丢弃
- 建议配合其他监控手段(如轮询
/v1/status)确保告警可靠性
资料来源:README.md:18
Docker 部署
Browser Gateway 提供官方的 Docker 镜像,支持在容器化环境中快速部署和运行。Docker 部署适合需要隔离、可移植性和易于扩展的生产环境。通过 Docker,用户可以快速启动网关服务,无需手动安装 Node.js 运行时和依赖项。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Browser Gateway 提供官方的 Docker 镜像,支持在容器化环境中快速部署和运行。Docker 部署适合需要隔离、可移植性和易于扩展的生产环境。通过 Docker,用户可以快速启动网关服务,无需手动安装 Node.js 运行时和依赖项。
官方镜像托管在 GitHub Container Registry (ghcr.io),镜像名为 ghcr.io/browser-gateway/server。每次发布新版本时都会构建并推送对应的 Docker 镜像,确保用户可以使用最新稳定版本。
快速开始
基础运行
使用以下命令可以快速启动 Browser Gateway 容器:
docker run -d \
-p 9500:9500 \
-v ./gateway.yml:/app/gateway.yml:ro \
-e PROVIDER_TOKEN=xxx \
ghcr.io/browser-gateway/server:latest
这个命令会:
- 以守护进程模式(-d)运行容器
- 将宿主机的 9500 端口映射到容器的 9500 端口
- 将本地的 gateway.yml 配置文件挂载到容器的 /app/gateway.yml(只读)
- 通过环境变量传递 Provider Token
端口说明
| 端口 | 协议 | 用途 |
|---|---|---|
| 9500 | HTTP/WebSocket | Gateway 主服务端口 |
容器内部网关监听 9500 端口,所有 HTTP REST API、WebSocket 连接和 Web Dashboard 都通过这个端口访问。
环境变量配置
Browser Gateway 支持通过环境变量进行配置。以下是常用的环境变量:
| 环境变量 | 必填 | 说明 |
|---|---|---|
PROVIDER_TOKEN | 是 | Provider 身份验证令牌 |
BG_TOKEN | 否 | Dashboard 访问认证令牌 |
BG_HOST | 否 | 绑定主机地址,默认为 0.0.0.0 |
BG_PORT | 否 | 监听端口,默认为 9500 |
BG_CONFIG | 否 | 配置文件路径,默认为 /app/gateway.yml |
设置 BG_TOKEN 后,Web Dashboard 将启用认证功能,用户需要通过安全的 HttpOnly Cookie 进行身份验证。
资料来源:.env.example
Docker Compose 部署
对于更复杂的部署场景,推荐使用 Docker Compose 进行管理。Docker Compose 可以同时管理网关服务、配置文件和环境变量。
基本配置示例
services:
browser-gateway:
image: ghcr.io/browser-gateway/server:latest
ports:
- "9500:9500"
volumes:
- ./gateway.yml:/app/gateway.yml:ro
environment:
- PROVIDER_TOKEN=${PROVIDER_TOKEN}
- BG_TOKEN=${BG_TOKEN}
restart: unless-stopped
生产环境配置
对于生产环境,建议添加健康检查、资源限制和日志配置:
services:
browser-gateway:
image: ghcr.io/browser-gateway/server:latest
ports:
- "9500:9500"
volumes:
- ./gateway.yml:/app/gateway.yml:ro
- gateway-data:/app/data
environment:
- PROVIDER_TOKEN=${PROVIDER_TOKEN}
- BG_TOKEN=${BG_TOKEN}
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9500/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 512M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
gateway-data:
资料来源:examples/docker-compose.yml
配置文件挂载
配置文件通过卷挂载方式传入容器,可以实现配置与容器镜像的分离,便于维护和更新。
配置挂载方式
# 只读挂载配置文件
-v ./gateway.yml:/app/gateway.yml:ro
# 读写挂载(用于保存配置变更)
-v ./gateway.yml:/app/gateway.yml:rw
Dashboard 中的配置编辑器支持直接修改配置文件。如果希望保存修改,需要使用读写挂载模式。
配置文件示例
providers:
- id: my-provider
endpoint: wss://provider.example.com
maxConcurrent: 5
healthy: true
pool:
maxConcurrent: 10
sessionTimeout: 300
server:
port: 9500
host: 0.0.0.0
资料来源:gateway.yml
网络配置
容器网络模式
Browser Gateway 需要与外部 Provider 建立 WebSocket 连接,确保容器可以访问外部网络:
graph LR
A[客户端] -->|HTTP/WebSocket| B[Browser Gateway 容器:9500]
B -->|WebSocket| C[外部 Provider]
B -->|WebSocket| D[本地 Provider]宿主机网络模式
如果需要让宿主机上的浏览器可以直接访问 CDP 端点,可以使用宿主机网络模式:
docker run -d \
--network host \
-v ./gateway.yml:/app/gateway.yml:ro \
-e PROVIDER_TOKEN=xxx \
ghcr.io/browser-gateway/server:latest
使用 --network host 时,容器共享宿主机的网络命名空间,可以直接访问宿主机的 localhost 服务。
代理配置
如果部署环境需要通过代理访问外部网络,需要配置代理环境变量:
environment:
- HTTP_PROXY=http://proxy.example.com:8080
- HTTPS_PROXY=http://proxy.example.com:8080
- NO_PROXY=localhost,127.0.0.1
健康检查
Docker 支持内置的健康检查机制,可以监控 Browser Gateway 的运行状态。
健康检查端点
Browser Gateway 提供 /health 端点用于健康检查:
curl http://localhost:9500/health
响应示例:
{
"status": "ok",
"uptime": 3600,
"providers": 2,
"activeConnections": 5
}
配置健康检查
在 docker-compose.yml 中配置健康检查:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9500/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
数据持久化
会话数据
Browser Gateway 支持会话持久化功能,用户的浏览器状态(Cookie、localStorage、页面状态)可以在断开重连后恢复。默认 TTL 为 5 分钟。
卷挂载
为确保数据持久化,需要挂载数据目录:
docker run -d \
-p 9500:9500 \
-v ./gateway.yml:/app/gateway.yml:ro \
-v ./data:/app/data \
ghcr.io/browser-gateway/server:latest
安全考虑
令牌管理
PROVIDER_TOKEN:Provider 身份验证,部署时通过环境变量注入BG_TOKEN:Dashboard 认证,建议使用强随机字符串
网络隔离
- 使用 Docker 网络隔离其他服务
- 通过防火墙限制对 9500 端口的访问
- 生产环境建议启用 HTTPS 反向代理
只读配置
配置文件使用 ro (read-only) 挂载选项,防止容器内修改配置:
-v ./gateway.yml:/app/gateway.yml:ro
镜像版本
版本标签
| 标签 | 说明 |
|---|---|
latest | 最新稳定版本 |
v0.2.0 | 指定版本 |
v0.1.8 | 历史版本 |
建议在生产环境中使用具体版本号,避免自动升级导致兼容性问题。
更新镜像
# 拉取最新版本
docker pull ghcr.io/browser-gateway/server:latest
# 重启容器
docker-compose down
docker-compose up -d
常见问题
容器启动失败
检查日志排查问题:
docker logs <container_id>
常见原因包括配置文件格式错误、端口冲突、环境变量缺失等。
WebSocket 连接问题
确保容器可以访问 Provider 的 WebSocket 端点,检查网络连通性和防火墙规则。
内存不足
浏览器操作需要较大内存,建议容器内存限制不少于 512MB,生产环境建议 2GB 以上。
相关文档
资料来源:.env.example
Provider 管理
Provider 是 browser-gateway 的核心概念之一,指代提供浏览器实例的后端服务。gateway 通过统一的管理接口,将请求路由到不同的 Provider,实现浏览器资源的高可用、负载均衡和故障转移。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
browser-gateway 支持接入多个浏览器提供方(Provider),包括:
| Provider 类型 | 示例 | 说明 |
|---|---|---|
| Playwright Server | ws://your-server:3000 | 自托管的 Playwright 服务 |
| 云端浏览器服务 | wss://provider.com?token=xxx | 第三方云服务 |
| Chrome DevTools Protocol | ws://localhost:9222 | 原生 Chrome/CDP 连接 |
| MCP 协议服务 | http://localhost:9500/mcp | MCP 兼容的浏览器服务 |
资料来源:web/src/app/(dashboard)/providers/page.tsx:55-75
核心功能
- 多 Provider 接入:同时管理多个浏览器后端服务
- 健康检查:实时监控 Provider 可用性
- 负载均衡:基于优先级和权重的请求分发
- 故障转移:Provider 不可用时自动切换
- 会话池:复用浏览器连接提升性能
- CRUD 操作:通过 Dashboard 或 API 动态管理
Provider 数据模型
ProviderConfig(配置)
定义 Provider 的静态配置信息:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 唯一标识符,使用小写字母和连字符 |
url | string | 是 | WebSocket 连接地址 |
priority | number | 否 | 优先级(数字越小优先级越高) |
weight | number | 否 | 权重(用于加权轮询) |
maxConcurrent | number | 否 | 最大并发连接数 |
cooldown | number | 否 | 故障后冷却时间(毫秒) |
timeout | number | 否 | 请求超时时间(毫秒) |
headers | Record<string, string> | 否 | 自定义请求头 |
ProviderState(运行时状态)
描述 Provider 的运行时状态:
| 字段 | 类型 | 说明 | |
|---|---|---|---|
id | string | Provider ID | |
config | ProviderConfig | 当前配置 | |
active | number | 当前活跃连接数 | |
healthy | boolean | 健康状态 | |
cooldownUntil | `number \ | null` | 冷却截止时间戳 |
failureCount | number | 连续失败次数 | |
successCount | number | 成功请求次数 | |
lastFailure | `number \ | null` | 最后失败时间戳 |
avgLatencyMs | number | 平均延迟(毫秒) | |
totalConnections | number | 历史总连接数 |
架构设计
graph TD
Client[客户端请求] --> Gateway[Browser Gateway]
Gateway --> Router[路由引擎]
Router --> HealthMonitor[健康监控]
Router --> LoadBalancer[负载均衡器]
LoadBalancer --> P1[Provider 1<br/>优先级: 1]
LoadBalancer --> P2[Provider 2<br/>优先级: 2]
LoadBalancer --> P3[Provider N<br/>优先级: N]
HealthMonitor -->|健康检查| P1
HealthMonitor -->|健康检查| P2
HealthMonitor -->|健康检查| P3
P1 -->|连接成功| Browser1[浏览器实例]
P2 -->|连接成功| Browser2[浏览器实例]
P3 -->|连接成功| Browsern[浏览器实例]
P1 -.->|故障| Cooldown[冷却期]
Cooldown -.->|恢复| P1请求路由流程
sequenceDiagram
participant C as 客户端
participant G as Gateway
participant R as 路由引擎
participant H as 健康检查
participant P as Provider
C->>G: POST /v1/screenshot
G->>R: 请求路由
R->>H: 检查 Provider 状态
H-->>R: Provider 可用
R->>P: 建立浏览器连接
P-->>R: 连接成功
R->>P: 导航到目标 URL
P-->>R: 截图数据
R-->>G: 返回结果
G-->>C: HTTP 响应Provider 配置管理
通过 Dashboard 配置
在 Dashboard 的 Providers 页面可以完成以下操作:
| 操作 | 入口 | 说明 |
|---|---|---|
| 查看列表 | /web/providers | 显示所有 Provider 及其状态 |
| 添加 Provider | 添加按钮 | 输入 ID、URL、优先级等 |
| 编辑 Provider | 编辑按钮 | 修改现有配置 |
| 删除 Provider | 删除按钮 | 移除 Provider 配置 |
| 测试连接 | 测试按钮 | 验证 Provider 连通性 |
资料来源:web/src/app/(dashboard)/providers/page.tsx:1-100
Provider ID 命名规范
- 使用小写字母
- 使用连字符
-分隔 - 示例:
playwright-local、cloud-browser-1
// 验证规则
/^[a-z][a-z0-9-]*$/
资料来源:web/src/app/(dashboard)/providers/page.tsx:30-35
WebSocket URL 格式
| 类型 | 格式 | 示例 |
|---|---|---|
| 自托管 | ws://host:port | ws://localhost:3000 |
| 云服务 | wss://host?token=xxx | wss://provider.com?token=xxx |
| 带认证 | wss://host?api_key=xxx | wss://cloud.browser.io?api_key=xxx |
健康检查机制
健康检查流程
graph LR
A[定时检查] --> B{连接成功?}
B -->|是| C[更新 healthy=true]
B -->|否| D[增加 failureCount]
D --> E{超过阈值?}
E -->|是| F[设置 cooldownUntil]
E -->|否| G[标记 unhealthy]
F --> H[等待冷却期]
H --> I{冷却期结束?}
I -->|是| J[重新尝试]健康检查实现
健康检查模块负责监控每个 Provider 的可用性:
// 检查间隔:默认 10 秒
// 冷却时间:默认 30 秒
// 失败阈值:连续 3 次失败
资料来源:src/core/providers/health.ts:1-50
冷却机制
当 Provider 连续失败达到阈值后,进入冷却状态:
| 配置项 | 默认值 | 说明 |
|---|---|---|
cooldown | 30000ms | 冷却持续时间 |
failureThreshold | 3 | 进入冷却的连续失败次数 |
冷却期间,该 Provider 不会被路由选中。冷却结束后,系统会重新尝试连接。
负载均衡策略
优先级选择
Provider 按 priority 字段排序,数字越小优先级越高。路由引擎优先选择优先级最高的可用 Provider。
graph TD
R[路由请求] --> Q{Provider 1 可用?}
Q -->|是| A[使用 Provider 1]
Q -->|否| Q2{Provider 2 可用?}
Q2 -->|是| B[使用 Provider 2]
Q2 -->|否| Q3{Provider 3 可用?}
Q3 -->|是| C[使用 Provider 3]
Q3 -->|否| E[返回错误]加权轮询
当多个 Provider 具有相同优先级时,使用权重进行加权轮询:
| Provider | Weight | 相对权重 |
|---|---|---|
| local-1 | 2 | 50% |
| local-2 | 1 | 25% |
| cloud-1 | 1 | 25% |
资料来源:web/src/app/(dashboard)/providers/page.tsx:85-95
并发控制
每个 Provider 可以设置 maxConcurrent 限制最大连接数:
providers:
- id: local-chrome
url: ws://localhost:9222
maxConcurrent: 5 # 最多同时 5 个连接
当达到上限时,路由引擎会尝试选择其他 Provider。
REST API 接口
获取 Provider 列表
GET /v1/providers
响应示例:
{
"success": true,
"data": [
{
"id": "playwright-local",
"url": "ws://localhost:3000",
"priority": 1,
"weight": 1,
"maxConcurrent": 10,
"cooldown": 30000,
"timeout": 30000,
"headers": {}
}
]
}
添加 Provider
POST /v1/providers
Content-Type: application/json
{
"id": "new-provider",
"url": "ws://new-server:9222",
"priority": 2,
"weight": 1,
"maxConcurrent": 5
}
更新 Provider
PUT /v1/providers/:id
Content-Type: application/json
{
"url": "ws://updated-server:9222",
"priority": 1
}
删除 Provider
DELETE /v1/providers/:id
测试 Provider 连接
POST /v1/providers/:id/test
用于验证 Provider 的 WebSocket 连接是否正常,返回连接延迟和健康状态。
配置示例
gateway.yml 完整配置
server:
port: 9500
host: "0.0.0.0"
providers:
- id: playwright-local
url: ws://localhost:3000
priority: 1
weight: 1
maxConcurrent: 10
cooldown: 30000
timeout: 30000
- id: cloud-browser-1
url: wss://cloud.provider.com?token=xxx
priority: 2
weight: 2
maxConcurrent: 20
cooldown: 60000
headers:
Authorization: "Bearer xxx"
pool:
minSessions: 1
maxSessions: 100
sessionTimeout: 300000
auth:
enabled: false
token: ""
多地域配置
providers:
- id: us-east-chrome
url: ws://us-east.browser.internal:9222
priority: 1
headers:
X-Region: us-east
- id: eu-west-chrome
url: ws://eu-west.browser.internal:9222
priority: 1
headers:
X-Region: eu-west
- id: backup-cloud
url: wss://backup.provider.com?token=xxx
priority: 3
weight: 1
监控与状态
Dashboard 状态指示
| 指示灯 | 颜色 | 含义 |
|---|---|---|
| ● | 绿色 | Provider 健康 |
| ● | 红色(闪烁) | Provider 不健康 |
| 徽章 | cooldown | Provider 处于冷却期 |
资料来源:web/src/app/(dashboard)/page.tsx:25-40
状态端点
GET /v1/status
返回所有 Provider 的实时状态:
{
"success": true,
"data": {
"providers": [
{
"id": "playwright-local",
"healthy": true,
"active": 3,
"maxConcurrent": 10,
"avgLatencyMs": 45,
"priority": 1
},
{
"id": "cloud-browser",
"healthy": false,
"active": 0,
"maxConcurrent": 20,
"avgLatencyMs": 0,
"priority": 2,
"cooldownUntil": 1699999999999
}
],
"sessions": 3,
"uptime": 86400
}
}
最佳实践
Provider 命名约定
- 使用描述性名称:
playwright-local、cloud-browser-prod - 包含环境标识:
chrome-staging、chrome-production - 包含区域信息:
us-east-1-chrome、eu-west-2-chrome
故障恢复策略
# 推荐配置:本地优先,云端备份
providers:
- id: local-primary
url: ws://localhost:9222
priority: 1
cooldown: 5000 # 本地故障快速恢复
- id: local-replica
url: ws://localhost:9223
priority: 1
cooldown: 5000
- id: cloud-backup
url: wss://cloud.provider.com?token=xxx
priority: 3
cooldown: 30000 # 云端较长冷却期
性能优化
| 优化项 | 建议值 | 说明 |
|---|---|---|
maxConcurrent | CPU 核心数 × 2 | 平衡并发与资源 |
cooldown | 30s - 60s | 避免频繁切换 |
timeout | 30s - 60s | 合理超时设置 |
高可用部署
graph TD
LB[负载均衡器] --> GW1[Gateway 实例 1]
LB --> GW2[Gateway 实例 2]
LB --> GW3[Gateway 实例 N]
GW1 --> P1[Provider Pool]
GW2 --> P1
GW3 --> P1
P1 --> PW1[Playwright 1]
P1 --> PW2[Playwright 2]
P1 --> PWn[Playwright N]
PW1 --> Chrome1[Chrome 实例]
PW2 --> Chrome2[Chrome 实例]
PWn --> Chromen[Chrome 实例]故障排除
常见问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| Provider 显示不健康 | WebSocket 连接失败 | 检查 URL 和网络连通性 |
| 连接数达到上限 | maxConcurrent 过低 | 调高或设为 unlimited |
| 频繁故障转移 | Provider 性能不足 | 升级硬件或增加 Provider |
| 冷却状态无法恢复 | 配置错误 | 检查 cooldown 配置 |
调试命令
# 测试 Provider 连通性
browser-gateway check
# 查看详细日志
DEBUG=provider:* browser-gateway serve
# 验证配置文件
browser-gateway config validate
相关文档
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
下游已经要求复核,不能在页面中弱化。
风险会影响是否适合普通用户安装。
Pitfall Log / 踩坑日志
项目:browser-gateway/browser-gateway
摘要:发现 6 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:能力坑 - 能力判断依赖假设。
1. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | README/documentation is current enough for a first validation pass.
2. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | last_activity_observed missing
3. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | no_demo; severity=medium
4. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | no_demo; severity=medium
5. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | issue_or_pr_quality=unknown
6. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | mcp_registry:io.github.browser-gateway/browser-gateway:0.1.8 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.browser-gateway%2Fbrowser-gateway/versions/0.1.8 | release_recency=unknown
来源:Doramagic 发现、验证与编译记录