终端连接让基于浏览器的 UI 可直接与沙箱 shell 交互。不同于使用 exec() 执行离散命令,终端连接会打开到 bash shell 的持久双向通道 — 与 SSH 或本地终端模拟器的模型相同。
终端连接使用 WebSocket 在浏览器终端(如 xterm.js ↗)与沙箱 container 内运行的伪终端 (PTY) 进程之间流式传输原始字节。
Browser (xterm.js) <-- WebSocket --> Worker <-- proxy --> Container PTY (bash)- 浏览器向你的 Worker 发送 WebSocket 升级请求
- 你的 Worker 调用
sandbox.terminal(request),将升级代理到 container - container 生成一个附加到 PTY 的 bash shell
- 原始字节双向流动 — 按键输入,终端输出
这与 exec() 有本质区别:
exec()运行单个命令至完成并返回结果terminal()打开持久 shell,用户可交互式输入命令
container 在环形缓冲区中缓冲终端输出。当客户端断开并重新连接时,服务器会重放缓冲输出,使终端看起来未发生变化。这意味着:
- 短暂的网络中断对用户不可见
- 重新连接的终端会显示先前输出,无需重新运行命令
- 缓冲区大小固定,因此非常旧的输出可能会丢失
无需客户端代码处理缓冲 — container 会透明地管理。
基于浏览器的应用中网络中断很常见。终端连接通过服务端缓冲(如上所述)与客户端指数退避重连的组合来处理此问题。
用于 xterm.js 的 SandboxAddon 会自动实现这一点。如果构建自定义客户端,你需要自行负责重连逻辑 — 无论哪个客户端连接,服务端缓冲都会工作。有关连接生命周期的详细信息,请参阅 WebSocket 协议参考。
每个会话可以有自己的终端,并具有独立的 shell 状态:
const devSession = await sandbox.createSession({
id: "dev",
cwd: "/workspace/frontend",
env: { NODE_ENV: "development" },
});
const testSession = await sandbox.createSession({
id: "test",
cwd: "/workspace",
env: { NODE_ENV: "test" },
});
// Each session's terminal has its own working directory,
// environment variables, and command history多个浏览器客户端可同时连接到同一会话的终端。它们都会看到相同的 shell 输出并可发送输入。将此模式用于同一工作区内的有意协作,而不是隔离独立用户。
终端连接为终端 I/O 使用二进制 WebSocket 帧(出于性能考虑),为控制和状态消息使用 JSON 文本帧(出于结构化考虑)。这使数据路径保持快速,同时仍允许对终端调整大小等操作进行结构化通信。
有关完整协议规范(包括连接生命周期和消息格式),请参阅 Terminal API 参考。
| 用例 | 方法 |
|---|---|
| 运行命令并获取结果 | exec() 或 execStream() |
| 面向终端用户的交互式 shell | terminal() |
| 带实时输出的长时间运行进程 | startProcess() + streamProcessLogs() |
| 协作式终端共享 | 使用共享会话的 terminal() |
- Terminal API 参考 — 方法签名和类型
- 浏览器终端 — 分步设置指南
- 会话管理 — 会话如何工作
- 架构 — 整体 SDK 设计