方式 B:作为节点
节点接入 backend、设备发现、云设备创建
节点会:发现控制网关 → 通过 /ws/daemon 完成 Hello/Welcome 注册 → 后台准备运行环境并发现、上报本机设备 → 接收并执行派发的 Flow、响应设备操作 RPC(DeviceOp)、推送运行事件与心跳;开启 webrtc 时为每台设备起媒体会话。
设备发现
节点始终枚举本机所有 adb 可见设备(USB 真机 + 虚拟/模拟器),不区分、无需指定 android。每台 adb 设备 meta 带 platform:"android"(驱动选择器)+ transport:"usb"|"virtual"。best-effort——缺 adb 只告警不致命。Desktop / iOS 为 opt-in,经 AIXAUTOSDK_NODE_PLATFORMS 显式开启。
1. 在 backend 签发 node token
节点归属注册它的调用方:必须带身份(项目 key/secret → 解析为该项目的代表用户,或用户 JWT bearer)。匿名注册返回 401。该节点上报的设备即归该用户。
curl -sX POST http://<backend>/api/nodes \
-H 'Content-Type: application/json' \
-H 'X-Project-Key: <PROJECT_KEY>' -H 'X-Project-Secret: <PROJECT_SECRET>' \
-d '{"name":"lab-node-1"}'
# → {"id":"...","token":"<NODE_TOKEN>"} token 仅此一次返回,妥善保存2. 运行节点
AIXAUTOSDK_BACKEND_URL=https://<backend> \
AIXAUTOSDK_NODE_TOKEN=<NODE_TOKEN> \
AIXAUTOSDK_NODE_NAME=lab-node-1 \
./aixautobot node| 变量 | 必填 | 默认 / 说明 |
|---|---|---|
AIXAUTOSDK_NODE_TOKEN | ✅ | backend 签发的节点 token |
AIXAUTOSDK_BACKEND_URL | https://aixautobot.com | |
AIXAUTOSDK_NODE_NAME | 默认取 $HOSTNAME | |
AIXAUTOSDK_NODE_OWNER_ID | Windows 宿主的稳定应用标识;不能使用 token。未设置时仅从可验证的独立父应用自动派生归属 | |
AIXAUTOSDK_NODE_PLATFORMS | 可选。adb 设备始终自动枚举;仅当要额外接入 desktop / ios 时填逗号列表 | |
AIXAUTOSDK_IOS_WDA_URL | ios opt-in 时 | 启用 ios 后端需设置 WDA 地址 |
AIXAUTOSDK_MAX_VIEWERS | WebRTC 单设备最大查看端,默认 4 |
Windows 启动时的孤儿节点处理
SDK 在连接网关前检查当前宿主、Windows 用户及会话、可执行文件、node_name 和 HTTPS 基础入口对应的归属登记。宿主可以注入稳定的 AIXAUTOSDK_NODE_OWNER_ID,例如自身应用标识;不要使用 token。未指定时,SDK 仅从可验证的独立父应用自动派生归属,通用 shell、解释器或共享浏览器进程不自动推断。
只有已登记的 node 进程同时通过精确创建时间、路径、SID/会话及父进程已退出或 PID 已复用的校验,才会被自动终止。启动事务串行执行,确认旧节点退出后才登记当前节点;已确认的孤儿无法清理时,会阻止新节点连接网关并提示 PID 和失败阶段。仍有活父进程的节点、MCP、其他用户及其他宿主不受影响。宿主也应将子进程树绑定自身生命周期;Windows Job 绑定失败不能视为启动成功。
历史 SDK 的未登记进程只记录候选孤儿 PID,不会按名称自动结束所有 aixautobot.exe。处理这类旧进程前,需核对实际可执行文件、命令、用户、父进程和创建时间。
backend_url=https://aixautobot.com 是 HTTPS 发现入口,实际控制网关由 /api/control-gateway 返回。宿主负责读取自己的 token 缓存并将 AIXAUTOSDK_NODE_TOKEN 注入子进程;SDK 不读取集成商的 token JSON。排查连接时应核对实际节点版本、PID、令牌是否注入、发现结果及网关注册确认,不能仅凭进程存在判断已上线;MCP 进程没有持续网关连接也不能证明节点认证失败。
SDK 独立启动诊断
Windows SDK 0.4.2 起,节点每次启动会建立独立的 JSONL 诊断会话,并在 stderr 打印实际文件路径。Windows 默认目录为 %LOCALAPPDATA%\aixautobot\logs。定位问题应使用当前 SDK 自身会话文件,按记录中的 UTC 时间、SDK 版本、PID 和会话标识核对本次启动;历史日志不能证明当前启动的状态。
诊断记录包含启动阶段、状态、分类后的失败原因,以及脱敏的端点或设备数量;收到 Welcome 时记录真实节点 ID,用于与界面核对,不能用宿主缓存中的占位 ID 代替。它不收集宿主应用或 MCP 的全部 stdout,也不保存 token、API key、project secret、原始远端消息或含凭据的完整 URL。SDK 自有 JSONL 文件的数量和单文件大小受限制;无法创建或写入时会在 stderr 明确提示,但不会仅因诊断写入失败阻止节点启动。
排查时区分配置读取、网关发现、握手、Hello/Welcome 注册和环境准备阶段。TCP Established 只证明传输连接存在,不能代替 Welcome;PATH 中 NOT_FOUND 不能证明 SDK 缓存或 WSL 中也没有该工具。阶段的 ready 或 completed 只表示该阶段所记录的条件达到或工作结束,不意味着所有设备、驱动、环境组件都已验证可用;需结合具体阶段及检测结果判断。
注册日志需按阶段判断:session_connect 的 ready 只表示 WebSocket 握手(HTTP 101)完成,不表示 Hello 已发送或节点已注册。SDK 0.4.3 起,session_hello 的 started / completed 分别记录开始发送和发送完成;随后 welcome 的 started 表示等待注册确认,ready 才表示收到 Welcome,并记录平台返回的真实节点 UUID。环境准备只在收到该确认后启动。
SDK 0.4.3 起,发送 Hello 最长等待 30 秒;发送完成后再以固定 30 秒期限等待 Welcome,心跳不会延长该期限。超时、注册前远端错误、无效 JSON 或连接关闭会记录分类失败,随后重新发现网关并退避重连,避免仅完成握手后无限等待。日志出现握手成功但缺少 Welcome 能定位注册阶段尚未完成,不能单凭此现象确定现场是认证、网络还是网关故障。
SDK 0.4.4 起,收到 WebSocket 关闭帧时,诊断会保留数值 close_code,并对已知静态原因作分类;注册确认前记录在 welcome 阶段,注册后记录在 session_connect 阶段,不保存远端原始关闭描述。连接直接结束而没有关闭帧时,记录 socket_eof,不会推测关闭码;无关闭详情或未知描述统一记录 socket_closed。结合关闭码、分类和当前会话阶段排查,不能把统一的 socket_closed 或其他会话的回调错误当作当前节点的确定根因。认证契约、重连行为和上述 30 秒期限保持不变。
3. 嵌入自己的二进制(可选)
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
aixautosdk::node::run().await // 读取上述 env,自带退避重连
}iOS 与虚拟 iOS(vphone)
两条 lane 均默认关闭、与 redroid 平行。iOS 一律按真机对待——无论物理机还是 vphone 云手机,上线后都经 usbmuxd/WDA 走统一的设备操作路径。
| Feature | 作用 | 设备 | 宿主 |
|---|---|---|---|
ios | 真机 iOS(go-ios 驱动) | USB 连接的 iPhone/iPad | 装有 go-ios(ios 二进制)的主机 |
vphone | 虚拟 iOS 云手机(外部 vphone-cli) | iOS VM | Apple Silicon + macOS 15+、关闭 SIP/AMFI |
- 路由:
provision按spec.platform="ios"/kind="vphone"走 vphone 创建(真机 iOS 只发现、不创建);power/device_control按设备 id 命名空间路由——ios-<udid>→ 真机 iOS,已注册的 vphone 实例 → vphone,其余 → redroid。功能未启用时返回明确的 “not enabled” 错误。 - 开启
iosfeature 时 helper 为唯一权威源:按udid枚举、为每台设备把 WDA 转发到各自独立的本地端口,设备 id =ios-<udid>。相关 env:AIXAUTOSDK_IOS_PYTHON、AIXAUTOSDK_IOS_USBMUXD、AIXAUTOSDK_IOS_WDA_LOCAL_PORT/_DEVICE_PORT。 - vphone 相关 env:
AIXAUTOSDK_VPHONE_CLI(预编译且签名的绝对路径)、AIXAUTOSDK_VPHONE_INSTANCES_DIR、AIXAUTOSDK_VPHONE_IPSW等。 - 能力上报:
Hello.capabilities含ios_capable/vphone_capable/redroid_capable,供后端按节点能力调度。
云设备创建:代理与安装包
创建云设备(POST /api/devices/provision)的 spec 支持两个平台无关的可选输入,设备上线后由节点自动应用:
| 字段 | 形态 | 说明 |
|---|---|---|
proxy | string(URL) | 代理地址。redroid 走原生 settings put global http_proxy;vphone/iOS 安装一份全局 HTTP 代理描述文件 |
packages | [{software, version?}] | 按 software + version 安装的包数组。version 省略时由平台管理员默认版本补齐 |
{
"platform": "ios", "name": "vm-01",
"proxy": "http://10.0.0.1:7890",
"packages": [
{ "software": "com.foo.app", "version": "1.2.3" },
{ "software": "com.bar.app" }
]
}- 解析器:节点按
(platform, software, version)向AIXAUTOSDK_PKG_RESOLVER指向的解析服务取包,下载并校验 sha256 后安装。 - 应用时机:provision 创建并
ensure_online后逐包安装 + 应用代理,best-effort——单项失败只告警、不致 provision 失败。
Mac 环境底座(aixautobot mac-env)
macOS 上把“装 lima → 建 Ubuntu VM → 加载 binder → 装 docker”这套环境底座固化为一键命令,使现有 redroid 创建路径开箱即用。只做底座,不创建设备、不注册节点。
aixautobot mac-env setup --json # 一键配置,逐行输出进度
aixautobot mac-env status --json # 只探测,报每步 ok|missing
aixautobot mac-env teardown [--purge]# 停 VM;--purge 连磁盘一起删setup 成功后产出 AIXAUTOSDK_DOCKER_SOCKET 与 AIXAUTOSDK_INSTANCES_DIR 两个变量;让本机 node 进程带上它们,之后走现有 POST /api/devices/provision 即可在该 VM 内创建 redroid 云手机。
节点基础入口只接受 HTTPS(本地开发允许 loopback HTTP)。SDK 通过 /api/control-gateway 发现实际 WSS 控制网关;发现失败时重试,不直连基础入口。旧 AIXAUTOSDK_BACKEND_WS 和旧 WS 配置不再支持,迁移时应删除并改用 AIXAUTOSDK_BACKEND_URL。自建部署必须提供有效的控制网关发现响应,或显式配置实际控制网关。