跳转到内容
搜索文档

终端连接

最后更新 查看 MarkdownAgent 设置

终端连接让基于浏览器的 UI 可直接与沙箱 shell 交互。不同于使用 exec() 执行离散命令,终端连接会打开到 bash shell 的持久双向通道 — 与 SSH 或本地终端模拟器的模型相同。

终端连接如何工作

终端连接使用 WebSocket 在浏览器终端(如 xterm.js)与沙箱 container 内运行的伪终端 (PTY) 进程之间流式传输原始字节。

Browser (xterm.js) <-- WebSocket --> Worker <-- proxy --> Container PTY (bash)
  1. 浏览器向你的 Worker 发送 WebSocket 升级请求
  2. 你的 Worker 调用 sandbox.terminal(request),将升级代理到 container
  3. container 生成一个附加到 PTY 的 bash shell
  4. 原始字节双向流动 — 按键输入,终端输出

这与 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 输出并可发送输入。将此模式用于同一工作区内的有意协作,而不是隔离独立用户。

WebSocket 协议

终端连接为终端 I/O 使用二进制 WebSocket 帧(出于性能考虑),为控制和状态消息使用 JSON 文本帧(出于结构化考虑)。这使数据路径保持快速,同时仍允许对终端调整大小等操作进行结构化通信。

有关完整协议规范(包括连接生命周期和消息格式),请参阅 Terminal API 参考

何时使用终端与命令

用例 方法
运行命令并获取结果 exec()execStream()
面向终端用户的交互式 shell terminal()
带实时输出的长时间运行进程 startProcess() + streamProcessLogs()
协作式终端共享 使用共享会话的 terminal()

相关资源

这篇文档对您有帮助吗?