跳转到正文

架构

高层流程

默认模式(本地 tmux + 隧道):

代码
Browser (phone)
  |
  | HTTPS
  v
Cloudflare Quick Tunnel
  |
  | HTTP/WS
  v
Local Termbridge server
  |
  | PTY
  v
Tmux session

直接沙盒模式(Daytona,无隧道):

代码
Browser (phone)
  |
  | HTTPS
  v
Daytona preview link
  |
  | HTTP/WS
  v
Termbridge server (sandbox)
  |
  | PTY
  v
Tmux session (sandbox)

设置 --no-tunnel 时,Termbridge 会跳过 Cloudflare,并使用你提供的公共 URL。

组件

CLI 进程

  • 启动提供 UI 资源的 HTTP 服务器。
  • 启动用于终端 I/O 的 WebSocket 服务器。
  • 创建一个或多个 tmux 会话(或 Daytona PTY)。
  • 签发一次性兑换令牌。
  • 启用隧道时启动并监控隧道(目前为 Cloudflare)。
  • 在直接沙盒模式下,于沙盒内启动 Termbridge,并等待共享 URL。

终端后端

  • tmux 后端:使用 node-pty 连接到 tmux,以传输真实的按键输入和输出。
  • Daytona 后端:在沙盒内使用 Daytona PTY。
  • 设置 TERM=xterm-256color 和 COLORTERM=truecolor 以完整支持颜色。
  • 对于 tmux,禁用 tmux 状态栏,让 UI 保持简洁。

终端注册表

  • 跟踪可用的终端会话。
  • 为 UI 提供列表,并验证所选终端 ID。

身份验证与会话

  • 一次性令牌会以 URL 打印,并编码在 QR 代码中。
  • GET /__tb/s/:token 兑换令牌并设置 Cookie 会话。
  • WebSocket 连接需要有效的会话 Cookie 和 CSRF 令牌。
  • 通过 GET /__tb/api/csrf 获取 CSRF 令牌,并通过 WebSocket 查询参数传递。

代理模式

传入 --proxy <port> 时:

  • 所有 termbridge 路由都位于 /__tb/ 前缀下
  • 非 /__tb/ 请求会代理到目标应用
  • UI 通过 Views 切换器提供 Terminal/Preview 视图
  • Preview 视图会加载指向 / 的 iframe
  • HMR 的 WebSocket 连接会转发到目标

安全

  • CSRF 防护:WebSocket 升级需要 CSRF 令牌,以防止跨站劫持。
  • 输入限制:HTTP 请求正文 64KB、WebSocket 消息 1MB、每条消息终端输入 64KB。
  • 速率限制:令牌兑换和 WebSocket 连接均按 IP 限制。

API 端点

所有路由都位于 /__tb/ 前缀下,以避免与代理应用冲突:

  • GET /__tb/healthz - 健康检查
  • GET /__tb/s/:token - 兑换令牌 → Cookie → 重定向
  • GET /__tb/api/terminals - 列出终端
  • GET /__tb/api/csrf - 获取 WebSocket 的 CSRF 令牌
  • GET /__tb/api/config - 获取配置(proxyPort、devProxyUrl)
  • POST /__tb/api/terminals - 创建新的 tmux 会话
  • GET /__tb/app/* - SPA 回退
  • WS /__tb/ws/terminal/:terminalId?csrf=<token> - 流式传输终端 I/O

启用代理模式时:

  • GET / - 重定向到代理应用(若禁用则转到 /__tb/app)
  • * /* - 代理到目标应用

WebSocket 协议

客户端 -> 服务器:

JSON
{ "type": "input", "data": "ls -la" }
{ "type": "resize", "cols": 120, "rows": 32 }
{ "type": "control", "key": "ctrl_c" }

服务器 -> 客户端:

JSON
{ "type": "output", "data": "..." }
{ "type": "status", "state": "connected" }

UI 技术栈

  • Vite + TanStack Router
  • xterm.js + Fit 插件 + WebGL 渲染器
  • 移动端优先布局,带固定输入栏
  • 自动重新连接,采用指数退避(最多重试 10 次)
  • 连接状态指示器