构建服务器与连接建立
构建服务器是一个公开的无状态 HTTP 服务。它颁发构建许可、代理 WebRTC 连接建立,并把任务分配给构建机器。它不看任何构建的内容,也不 拥有读取 WebRTC 通道流动的用户数据的密码学权限。
端点
构建服务器暴露一个小型 REST 接口:
| 方法 | 路径 | 用途 |
|---|---|---|
POST | /grant/request | 申请构建许可。 |
POST | /signaling/{job_id}/offer | 提交 WebRTC SDP offer。 |
POST | /signaling/{job_id}/candidate | 提交 ICE 候选。 |
GET | /signaling/{job_id}/events | 实时推送流,推送构建机器的 answer 和候选。 |
GET | /health | 存活检查。 |
GET | /metrics | Prometheus 指标。 |
还有 /agents/* 和 /services/* 端点供构建机器和运维使用,但那些
不是面向用户的构建流程的一部分。
一次许可请求的细节
POST /grant/request
{
"peer_fingerprint": "sha-256:XX:XX:...",
"required_channels": ["espctl", "pty", "firmware"],
"cpu_cores": 2.0,
"memory_mb": 1024,
"timeout_secs": 600
}
| 字段 | 含义 |
|---|---|
peer_fingerprint | 请求方 peer 证书的 SHA-256 指纹。构建服务器把它嵌入许可,这样构建机器之后能验证“我正在通信的 peer 与许可颁发的 peer 是同一个“。 |
required_channels | 请求方需要的 WebRTC 数据通道精确列表。构建机器会拒绝打开不在此列表里的任何通道。 |
cpu_cores / memory_mb | 资源需求,用于把任务调度到有能力的构建机器。 |
timeout_secs | 会话允许存活多久。受运维策略限制(许可通常 5-30 秒,构建会话特别会更长)。 |
构建服务器回复:
{
"job_id": "01H...uuid",
"grant": "<签名 token>",
"candidates": ["agent-id-1", "agent-id-2"],
"ice_servers": [
{ "urls": "stun:stun.example.com:3478" },
{
"urls": "turn:stun.example.com:3478?transport=tcp",
"username": "...",
"credential": "..."
}
],
"expires_at": 1712340060
}
grant 是一个签名 token(用加密签名对编码后的 body 签名),记录
用户、允许的通道、带宽/速率限制和过期时间。构建机器在执行它之前,
会本地验证这个签名 —— 见 构建许可与安全。
连接建立 —— 构建服务器能看到什么、不能看到什么
构建服务器在两个 peer 之间转发 SDP offer/answer 和 ICE 候选。它不解析
内容 —— 把 body 当作不透明字节存,在匹配 job_id 的实时推送流上
广播,会话结束后丢弃状态(默认 60 秒 TTL)。
构建服务器看到什么:
- 在时间 T,指纹为 X 的 peer 请求了一个会话。
- N 字节的 SDP offer 被 POST 了。
- M 字节的 SDP answer 被转发了。
- 几个带地址的 ICE 候选(候选地址是唯一暴露的网络元数据;这是 WebRTC 工作方式的根本)。
构建服务器没看到什么:
- 构建请求 body(在数据通道上加密)。
- 构建日志(数据通道)。
- 固件二进制(数据通道)。
- 用户项目文件的内容(数据通道)。
任务分配
许可颁发后,构建服务器跑一个小型调度器挑哪个构建机器该跑这个任务。 调度器的输入:
- 存活 —— 构建机器每隔几秒心跳;只有存活的构建机器是候选。
- 容量 —— 许可请求里的
cpu_cores和memory_mb。 - 能力 —— 这个构建机器装了请求的 IDF 版本吗?支持请求的芯片 target 吗?
- 历史表现 —— 一个小型“学习引擎“偏好最近成功跑过类似任务的 构建机器。
被选中的构建机器通过实时推送收到许可,然后负责打开它那一半的 WebRTC peer connection。
运维关注点
如果你自己运行构建服务器:
- CORS:
/grant/*和/signaling/*端点是从浏览器调用的,所以 CORS 必须允许相关 origin。编辑/etc/aegis/control.env中的ALLOWED_ORIGINS然后重启服务。 - TLS: 公开端点在生产环境应该走 HTTPS。esphome.cloud 用 Caddy 做反向代理,自动 Let’s Encrypt 证书;IP 模式安装用 80 端口纯 HTTP (仅开发用)。
- TURN 端口: TURN 中继需要 49152-49231 UDP 端口供 peer 流量, TCP+UDP 3478 供 STUN/TURN 控制通道。
- 健康监控:
GET /health返回 200 + 一段小 JSON;GET /metrics返回 Prometheus 格式的指标。
aegis 仓库的 deploy/ 目录有完整的 systemd 单元文件、Caddyfile 模板
和 provision-store.sh 脚本。
另见
- WebRTC 构建机器与数据通道 —— 数据通道开了之后会发生什么。
- 构建许可与安全 —— 实际签名和验证什么。