Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

系统总览

本章是 30,000 英尺高度的视角:一次构建请求怎么从你的键盘(或浏览器) 走到一个编译好的 .bin,再走回来。后面三章会拉近镜头,看每一层。

角色

组件在哪里运行做什么
你的客户端你的笔记本支持 MCP 的 AI 客户端(Claude Code、Cursor、…)或 esphome.cloud 浏览器向导。
espctl mcp serve你的笔记本构建机器MCP 服务。把 MCP 工具调用翻译为本地计划,或者通过 WebRTC 翻译为远程构建请求。
构建服务器一台公开的 Linux 主机颁发构建许可,代理 WebRTC 连接建立,把任务分配给构建机器。从不接触构建本身。
构建机器一台带 IDF 工具链的私有 Linux 主机在沙箱里跑实际构建。通过 WebRTC 数据通道与你的客户端通信。
store构建机器上的硬盘装着所有已安装的 IDF 版本和工具链的目录。

一次构建怎么流动

┌────────────────┐
│  你的客户端    │
│ (IDE 或浏览器) │
└────┬───────────┘
     │ ① "给我编译一个 esp32s3 固件"
     ▼
┌────────────────┐    ② 许可请求              ┌─────────────────┐
│ MCP 服务       │───────────────────────────►│ 构建服务器      │
│ (espctl)       │◄───────────────────────────│ - 颁发许可      │
└────┬───────────┘    ③ 许可 + ICE 服务       │ - 挑构建机器    │
     │                                        └─────────┬───────┘
     │ ④ SDP offer (POST /signaling/.../offer)         │
     │                                                  │ ⑤ 事件
     │                                                  ▼ 流
     │                                            ┌─────────────┐
     │                                            │  构建机器    │
     │                                            └────┬────────┘
     │ ⑥ WebRTC 点对点连接                            │
     │ ◄──────────────────────────────────────────────►
     │
     │ ⑦ BuildRequest 在 espctl 通道上
     │ ⑧ 日志流式在 pty 通道上
     │ ⑨ 固件字节在 firmware 通道上
     ▼
┌────────────────┐
│ 结果: .bin     │
│ + 尺寸报告     │
│ + 清单         │
└────────────────┘

编号步骤:

  1. 你向 AI 客户端发问(或在浏览器向导中点按钮)。
  2. MCP 服务(或浏览器)向构建服务器 POST 一个构建许可请求: “我想要一个 构建会话,带 espctlptyfirmware 通道,最长 30 秒。” (长会话用单独的、更长有效期的许可。)
  3. 构建服务器返回一个签名的许可,挑出一个或多个有能力跑这个任务的 候选构建机器,并附上 STUN/TURN ICE 服务列表用于 WebRTC 握手。
  4. MCP 服务向连接建立端点 POST 一个 SDP offer。
  5. 被选中的构建机器 —— 它一直在定期查看构建服务器有没有新任务 —— 通过 实时推送抓到许可,准备接收 offer。
  6. WebRTC ICE 协商发生。两边通过构建服务器交换候选(构建服务器纯粹做 转发,它从不看 SDP 体的内容),最终聚合到要么直接点对点连接、要么 TURN 中继的连接。
  7. 数据通道开了之后,客户端在 espctl 通道上发送 BuildRequest。 构建机器在本地验证许可签名,开始构建。
  8. 随构建进行,构建机器在 pty 通道上流回 idf.py 的 stdout/stderr, 在 espctl 通道上发结构化的流水线事件。
  9. 构建成功后,构建机器把固件二进制分块,在 firmware 通道上流回, 最后再发一个 SHA-256 用于校验。

构建本身在构建机器上的沙箱里运行 —— 它无法读或写构建机器为它准备的 工作区目录之外的任何东西。

三层,三个职责

这是后面架构章节展开的三层模型:

  • 构建服务器与连接建立 —— 公开、无状态,知道但不知道 什么。颁发许可。转发 SDP。永远没有解密任何东西的权限。
  • WebRTC 构建机器与数据通道 —— 私有,跑构建,逐客户端 执行通道白名单和带宽限制。拥有完整的代码执行权限,但仅限沙箱内。
  • 构建许可与安全 —— 把上述两者绑在一起的密码学协议。 许可是一个签名 token,说“这个用户在这段时间里能用这些通道“。

为什么是这种形状?

架构的设计理念是让公开面(构建服务器)无状态且不可信。攻陷 构建服务器让你拿到颁发许可的能力,但许可没有构建机器配合就没用 —— 而构建机器会用编译时嵌入的、它信任的公钥在本地校验许可签名。

反过来,攻陷一个构建机器让你拿到当前在沙箱里跑的代码,但构建机器无法 冒充其他用户或颁发许可。构建机器本质上是“在沙箱里跑不可信代码的昂贵 机器“ —— 这正是沙箱被设计用来对付的威胁模型。

数据通道本身尽可能直接点对点,所以构建日志和固件二进制不会 经过构建服务器。这意味着运营构建服务器的人即使想读你的构建日志或固件 镜像,也无法做到。

接下来读哪里