Skip to content

用于 XXTouch 1.3.8+ 的云控服务端(WebSocket + 静态前端)与管理面板。

Notifications You must be signed in to change notification settings

havonz/XXTCloudControl

Repository files navigation

XXTCloudControl

用于 XXTouch 1.3.8-20260122000000+ 的云控服务端(WebSocket + 静态前端)与管理面板。
设备端协议实现源码位于设备端 /var/mobile/Media/1ferver/bin/open-cloud-control-client.lua

Screenshot

发布地址

项目结构

  • server/ - 后端 WebSocket/HTTP 服务(入口 server/main.go
  • frontend/ - 管理面板(SolidJS),源码在 frontend/src/,构建产物在 frontend/dist/
  • device-client/ - Lua WebSocket 客户端库
  • XXT 云控设置.lua - 设备端配置脚本(写入云控地址)
  • build.sh - 构建并打包多平台服务端 + 前端
  • build/ - 构建产物目录
  • server/data/ - 运行时数据目录(默认 data_dir=./data,取决于启动目录)

功能特点

  • WebSocket 实时通信、设备状态同步
  • 前端面板 + 后端一体化部署(服务端可直接托管静态前端)
  • 设备批量控制:脚本、触控、按键、重启/注销、剪贴板
  • WebRTC 实时桌面控制(可选内置 TURN 穿透)
  • 设备分组与脚本配置(FormRunner 动态表单)
  • 服务器端文件仓库(scripts/files/reports)+ 设备/服务器双向文件传输(小文件 WS,大文件 HTTP Token)
  • control/http 代理到设备本地 HTTP(用于 WebRTC 等设备 API)

快速开始

直接下载二进制运行(推荐)

  1. 打开发布页并下载最新 XXTCloudControl-<YYYYMMDDHHMM>.zip
    https://github.com/havonz/XXTCloudControl/releases
  2. 解压后进入目录,按系统运行对应二进制:
    # macOS (Apple Silicon 示例)
    chmod +x ./xxtcloudserver-darwin-arm64
    ./xxtcloudserver-darwin-arm64
    
    # Linux (amd64 示例)
    chmod +x ./xxtcloudserver-linux-amd64
    ./xxtcloudserver-linux-amd64
    
    # Windows (PowerShell)
    .\xxtcloudserver-windows-amd64.exe
  3. 首次启动会在当前目录生成 xxtcloudserver.json 并输出随机密码(只显示一次)。
  4. 浏览器访问 http://<服务器地址>:46980 登录管理面板。
  5. 如果忘记密码,可在同一目录重置后重启服务:
    # macOS (Apple Silicon 示例)
    ./xxtcloudserver-darwin-arm64 -set-password 12345678
    
    # Linux (amd64 示例)
    ./xxtcloudserver-linux-amd64 -set-password 12345678
    
    # Windows (PowerShell)
    .\xxtcloudserver-windows-amd64.exe -set-password 12345678

Docker 部署

快速启动(推荐)

docker pull havonz/xxtcloudcontrol
docker run --rm \
  -v "$PWD/xxtcc-data:/app/data" \
  havonz/xxtcloudcontrol \
  -config /app/data/xxtcloudserver.json -set-password 12345678
docker run -d --name xxtcloudcontrol \
  -p 46980:46980 \
  -p 43478:43478/tcp -p 43478:43478/udp \
  -v "$PWD/xxtcc-data:/app/data" \
  -e XXTCC_CONFIG=/app/data/xxtcloudserver.json \
  -e XXTCC_TURN_PUBLIC_IP="" \
  -e XXTCC_TURN_PUBLIC_ADDR="" \
  havonz/xxtcloudcontrol

提示:如果你不挂载数据目录,默认会在容器内 /app/data 生成数据与配置。 服务启动时会按顺序读取:配置文件 → 环境变量覆盖。环境变量不会自动写回配置文件。 环境变量名称可参考 docker-compose.yml 示例

使用 docker-compose.yml 一键部署

docker-compose.yml

mkdir -p XXTCloudControl && cd XXTCloudControl
curl -L -o docker-compose.yml https://raw.githubusercontent.com/havonz/XXTCloudControl/main/docker-compose.yml
docker compose up -d

生产/打包(源码构建)

依赖:gonpmzip

bash build.sh

产物输出在 build/,包含各平台二进制与打包的 zip:

build/
├── xxtcloudserver-<os>-<arch>[.exe]
├── ...
└── XXTCloudControl-<YYYYMMDDHHMM>.zip

解压后目录结构如下:

XXTCloudControl/
├── frontend/
├── xxtcloudserver-darwin-arm64
├── xxtcloudserver-linux-amd64
└── xxtcloudserver-windows-amd64.exe

在该目录内选择与你系统匹配的二进制运行即可自动托管前端(默认 frontend_dir=./frontend)。

Docker 镜像构建

依赖:docker(需启用 buildx)

bash build-docker.sh

产物输出在 build/

XXTCloudControl-docker-<YYYYMMDDHHMM>-linux-amd64.tar
XXTCloudControl-docker-<YYYYMMDDHHMM>-linux-arm64.tar

开发模式

  1. 启动后端:

    cd server
    go run .

    首次启动会在当前目录生成 xxtcloudserver.json 并输出随机密码(只显示一次)。

  2. 启动前端开发服务器:

    cd frontend
    npm install
    npm run dev

    访问 http://localhost:3000,在登录页输入服务器地址与端口(默认 46980)以及密码。

    提示:开发服务器默认绑定 127.0.0.1:3000,并将 /api 代理到 http://127.0.0.1:46980。若后端不在本机,请调整 frontend/vite.config.ts 或使用反向代理。

注意:go run .server 目录启动时,默认 frontend_dir./frontend,不会自动指向 ../frontend/dist。若希望后端托管前端,请在配置里设置 frontend_dir,或使用打包后的目录结构。

修改密码

./xxtcloudserver-<os>-<arch> -set-password 12345678

或在源码模式:

cd server
go run . -set-password 12345678

常用命令行参数

  • -config <path>:指定配置文件路径(默认使用启动目录的 xxtcloudserver.json
  • -set-password <pwd>:修改控制端密码
  • -set-turn-ip <ip>:设置 TURN 公网 IP 并启用
  • -set-turn-port <port>:设置 TURN 监听端口并启用
  • -v / -h:查看版本 / 帮助

配置说明

默认配置文件:xxtcloudserver.json(在启动目录生成)

{
  "port": 46980, // WebSocket 服务端口
  "passhash": "hex-string", // 密码的 HMAC-SHA256 哈希值
  "ping_interval": 15, // 服务端发送 WebSocket PING 心跳的间隔(秒)
  "ping_timeout": 10, // 设备连续未响应次数阈值,超过则断开连接
  "state_interval": 45, // 服务端请求设备状态 (app/state) 的间隔(秒)
  "frontend_dir": "./frontend", // 前端文件目录
  "data_dir": "./data", // 服务端数据目录
  "tlsEnabled": false, // 是否启用 TLS(HTTPS/WSS)
  "tlsCertFile": "./certs/server.crt", // TLS 证书文件路径
  "tlsKeyFile": "./certs/server.key", // TLS 私钥文件路径
  "turnEnabled": true, // 是否启用 TURN 服务器
  "turnPort": 43478,   // TURN 服务器监听端口(默认 43478)
  "turnPublicIP": "你的公网IP", // 公网 IP(需验证格式)
  "turnPublicAddr": "turn.example.com", // 公网地址(IP 或域名,无验证)
  "turnRealm": "xxtcloud", // TURN realm
  "turnSecretKey": "你的密钥", // TURN REST 密钥(留空会自动生成)
  "turnCredentialTTL": 86400, // TURN 凭据有效期(秒)
  "turnRelayPortMin": 49152, // TURN 服务器中继端口范围起始
  "turnRelayPortMax": 65535, // TURN 服务器中继端口范围结束
  "customIceServers": [] // 自定义 ICE 服务器列表(见下文)
}
  • passhashhmacSHA256("XXTouch", password) 的结果,不是明文密码。
  • ping_interval 控制心跳检测频率,服务端每隔该时间向设备发送 WebSocket PING 帧,用于检测设备在线状态。
  • state_interval 控制状态刷新频率,服务端每隔该时间向设备发送 app/state 请求以获取最新设备状态。
  • ping_timeout 表示设备连续未响应的次数阈值(基于 ping_interval 的周期),超过后服务端断开该设备连接。
  • data_dir 默认生成 scripts/files/reports/ 以及分组/脚本配置等持久化数据。
  • 配置中的路径均相对启动目录;在 server/ 目录启动时,默认 data_dir=./data 会落在 server/data/
  • turnEnabled 默认为 true,但仅在配置了 turnPublicIPturnPublicAddr 时才会实际启动内置 TURN。

WebRTC 穿透 (TURN) 配置

为了支持外网环境下的实时桌面控制,服务端内置了支持 UDP/TCP 的 TURN 服务器。

TURN 地址配置

服务端支持两种公网地址配置方式:

字段 格式 验证 适用场景
turnPublicIP 仅 IPv4 地址 net.ParseIP() 验证 有固定公网 IP
turnPublicAddr IPv4 或域名 域名自动 DNS 解析 使用域名访问

Important

仅支持 IPv4:TURN 服务器目前仅支持 IPv4 地址。IPv6 地址或仅有 AAAA 记录的域名会导致启动失败。

如果两者都配置,turnPublicIP 优先。只需配置其中一个即可启用内置 TURN。

配置示例:

// 方式 1: 使用 IP
{
  "turnEnabled": true,
  "turnPublicIP": "203.0.113.1"
}

// 方式 2: 使用域名
{
  "turnEnabled": true,
  "turnPublicAddr": "turn.example.com"
}

自定义 ICE 服务器

除了使用内置 TURN 服务,你还可以配置外部 STUN/TURN 服务器。这在以下场景很有用:

  • 不想在本地启用 TURN 服务,而是使用第三方 TURN 服务(如 Metered
  • 需要将本地 TURN 与外部服务合并使用,增强穿透能力

Warning

安全提示customIceServers 中的配置(包括 usernamecredential)会在 WebRTC 连接时发送给设备端,不是保密信息。请使用支持临时凭据的 TURN 服务,或确保凭据可公开共享。

配置示例:

{
  "turnEnabled": false,
  "customIceServers": [
    {
      "urls": ["stun:stun.relay.metered.ca:80"]
    },
    {
      "urls": ["turn:global.relay.metered.ca:80"],
      "username": "your-username",
      "credential": "your-credential"
    },
    {
      "urls": ["turn:global.relay.metered.ca:80?transport=tcp"],
      "username": "your-username",
      "credential": "your-credential"
    },
    {
      "urls": ["turn:global.relay.metered.ca:443"],
      "username": "your-username",
      "credential": "your-credential"
    },
    {
      "urls": ["turns:global.relay.metered.ca:443?transport=tcp"],
      "username": "your-username",
      "credential": "your-credential"
    }
  ]
}

合并行为:

本地 TURN 自定义 ICE Servers 结果
启用 仅使用本地 TURN
禁用 仅使用自定义 ICE Servers
启用 合并:本地 TURN + 自定义 ICE Servers
禁用 无 ICE 服务器,WebRTC 仅尝试直连

快捷设置命令

# 设置公网 IP 并启用
./xxtcloudserver -set-turn-ip 1.2.3.4

# (可选) 设置监听端口 (默认 43478)
./xxtcloudserver -set-turn-port 3478

Tip

turnSecretKey 为空时会在启动时自动生成临时密钥(重启会变化),如需稳定的 TURN 凭据请手动配置。

管理员防火墙配置

服务器管理员需要在云安全组/防火墙中开放以下端口:

端口范围 协议 用途
46980 (或自定义) TCP 云控本体服务 (API & WebSocket)
43478 (或自定义) UDP & TCP WebRTC [TURN] 控制、握手与回退
49152 - 65535 UDP WebRTC [TURN] 实时媒体流中继

Tip

媒体中继优先使用 UDP。在 UDP 流量被严格限制的情况下,WebRTC 会自动回退到 TCP (端口 43478) 以确保桌面流能够正常传输。

TLS/HTTPS 配置 (可选)

服务端支持原生 HTTPS/WSS,无需反向代理即可启用加密连接。同时也兼容通过 Nginx/Caddy 等反向代理的方式。

1) 配置 TLS

xxtcloudserver.json 中设置:

{
  "tlsEnabled": true,
  "tlsCertFile": "./certs/server.crt",
  "tlsKeyFile": "./certs/server.key"
}

2) 生成本地测试证书

mkdir -p certs
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \
  -keyout certs/server.key -out certs/server.crt \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

Warning

自签名证书仅适用于本地测试。生产环境请使用 Let's Encrypt 或其他 CA 签发的证书。

3) 反向代理模式

如果使用 Nginx/Caddy 等反向代理,服务端可保持 HTTP 模式运行,由代理处理 TLS 终止。此时绑定脚本会通过 X-Forwarded-Proto 请求头自动检测协议并生成正确的 wss:// 地址。

Nginx 配置示例:

server {
    listen 443 ssl;
    server_name your-domain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass http://127.0.0.1:46980;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
    location /api/ws {
        proxy_pass http://127.0.0.1:46980;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

设备绑定方式

  1. 运行脚本 XXT 云控设置.lua,填写 ws://<host>:46980/api/ws(TLS 或反向代理场景使用 wss://)。
  2. 或下载自动生成的绑定脚本: http://<host>:46980/api/download-bind-script?host=<host>&port=46980
    可追加 proto=https 强制生成 wss:// 地址;反向代理场景也可由 X-Forwarded-Proto 自动识别。
  3. 或手动调用设备本地接口:
    PUT http://127.0.0.1:46952/api/config
    
    {
      "cloud": {
        "enable": true,
        "address": "ws://<host>:46980/api/ws"
      }
    }

关闭云控:将 enable 置为 false

WebSocket 约定

  • WebSocket 地址:ws://<host>:<port>/api/ws(TLS/反代场景使用 wss://
  • 控制端消息需包含 ts/nonce/sign,时间戳允许 ±60 秒漂移,nonce 在 120 秒内不可重复。

鉴权与签名算法(HTTP/WS 通用)

本项目的鉴权不使用固定 token,而是使用「短时效动态签名」:客户端每次请求携带当前秒级时间戳 ts、随机 nonce 与签名 sign,服务端在允许的时间窗口内校验签名正确性,并做 nonce 去重。

1) 密码与 passhash

服务端配置文件 xxtcloudserver.json 中保存的是 passhash(不是明文密码):

  • passhash = HMAC-SHA256(key="XXTouch", message=password),结果为 64 位十六进制字符串(hex)。

2) sign 计算方式

控制签名使用 passhash 作为 HMAC key,对规范化后的基串做 HMAC:

HTTP 基串

base = ts "\n" nonce "\n" METHOD "\n" PATH_AND_QUERY "\n" bodyHash
  • METHOD:请求方法(GET/POST/PUT/DELETE…)
  • PATH_AND_QUERYpath + 排序后的 query(去除 ts/nonce/sign
  • bodyHash
    • 普通请求体:SHA-256(bodyBytes) 的 hex
    • 空 body 或 multipart(multipart/form-data)暂不参与:bodyHash = ""

WebSocket 基串

base = ts "\n" nonce "\n" type "\n" bodyHash
  • type:消息类型(如 control/devices
  • bodyHash:对 body 的 JSON 结果做 SHA-256(hex);没有 body 则为空字符串

最终签名:

  • sign = HMAC-SHA256(key=passhash, message=base),结果为 hex 字符串。

注意:这里的 key=passhash 指的是 passhash 的 hex 字符串本身(按字符串字节参与 HMAC),不是把 hex 解码为 32 字节后再参与计算。

3) 服务端校验规则

  • 允许的时间漂移:ts 在服务端当前时间 ±60 秒内才会继续校验。
  • nonce120 秒内不可重复(重复视为重放)。
  • 校验失败返回 401 Unauthorized(HTTP)或直接关闭连接(WebSocket 控制端消息)。

4) HTTP API 鉴权方案

http 下载绑定脚本外,所有 HTTP API 都需要携带签名(与 WebSocket 相同的算法):

  • 受保护路径:所有 /api/*
  • 放行:
    • /api/download-bind-script(按你的要求保留无需签名)
    • /api/config(前端启动配置)
    • /api/control/info(JSON 版配置输出)
    • /api/ws(WebSocket 升级握手不做 HTTP 鉴权;控制端消息仍需签名)
    • /api/transfer/download/:token(临时 token 下载)
    • /api/transfer/upload/:token(临时 token 上传)
    • OPTIONS 预检请求(CORS)

HTTP 请求可用两种携带方式(二选一):

  1. 请求头(推荐)

    • X-XXT-TS: <ts>
    • X-XXT-Nonce: <nonce>
    • X-XXT-Sign: <sign>
  2. Query 参数(适用于下载/window.open/img 等无法方便加自定义 header 的场景)

    • ?ts=<ts>&nonce=<nonce>&sign=<sign>

示例:

# 查询分组(header 方式)
curl -sS \
  -H "X-XXT-TS: 1700000000" \
  -H "X-XXT-Nonce: <nonce>" \
  -H "X-XXT-Sign: <hex-sign>" \
  http://127.0.0.1:46980/api/groups

# 下载服务器文件(query 方式)
curl -L -o out.bin \
  "http://127.0.0.1:46980/api/server-files/download/scripts/demo.lua?ts=1700000000&nonce=<nonce>&sign=<hex-sign>"

控制端通用消息格式

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command|control/commands|control/devices|control/refresh",
  "body": {}
}

HTTP 代理(control/http)

控制端可通过 WebSocket 发送 control/http,将 HTTP 请求转发到设备(设备侧以 http.request 执行),常用于 WebRTC 相关接口。

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/http",
  "body": {
    "devices": ["udid1"],
    "requestId": "uuid",
    "method": "POST",
    "path": "/api/webrtc/start",
    "query": {},
    "headers": { "Content-Type": "application/json" },
    "body": "base64-json",
    "port": 46952
  }
}

说明:body 需要 base64 编码;当请求为 /api/webrtc/start 且 TURN 已启用时,服务端会自动注入 iceServers

设备端上线

设备端发送 app/state,并在 body.system.udid 中提供唯一标识。

设备断开

服务端通知控制端:

{
  "type": "device/disconnect",
  "body": "udid"
}

设备列表

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/devices"
}

响应:

{
  "type": "control/devices",
  "body": {
    "udid1": {},
    "udid2": {}
  }
}

刷新设备状态

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/refresh"
}

服务端会向所有设备广播 app/state 请求。

实时日志订阅

订阅指定设备日志:

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/log/subscribe",
  "body": { "devices": ["udid1"] }
}

取消订阅:

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/log/unsubscribe",
  "body": { "devices": ["udid1"] }
}

设备端若支持日志推送,会发送:

{
  "type": "system/log/push",
  "udid": "udid1",
  "body": { "chunk": "log line..." }
}

批量命令

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/commands",
  "body": {
    "devices": ["udid1", "udid2"],
    "commands": [
      { "type": "script/run", "body": { "name": "demo.lua" } },
      { "type": "screen/snapshot", "body": { "format": "png", "scale": 30 } }
    ]
  }
}

常用命令类型

文件操作

上传文件

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "file/put",
    "body": {
      "path": "/scripts/xxx.lua",
      "data": "Base64数据"
    }
  }
}

创建目录

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "file/put",
    "body": {
      "path": "/scripts/dir",
      "directory": true
    }
  }
}

列出目录

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "file/list",
    "body": {
      "path": "/scripts"
    }
  }
}

下载文件

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "file/get",
    "body": {
      "path": "/scripts/xxx.lua"
    }
  }
}

拷贝文件

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "file/copy",
    "body": {
      "from": "/scripts/xxx.lua",
      "to": "/scripts/yyy.lua"
    }
  }
}

移动文件

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "file/move",
    "body": {
      "from": "/scripts/xxx.lua",
      "to": "/scripts/yyy.lua"
    }
  }
}

删除文件

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "file/delete",
    "body": {
      "path": "/scripts/xxx.lua"
    }
  }
}

设备控制

注销设备

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1", "udid2"],
    "type": "system/respring"
  }
}

重启设备

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1", "udid2"],
    "type": "system/reboot"
  }
}

触控命令

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1", "udid2"],
    "type": "touch/down|touch/move|touch/up",
    "body": {
      "x": 100,
      "y": 200
    }
  }
}

按键命令

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1", "udid2"],
    "type": "key/down|key/up",
    "body": {
      "code": "HOMEBUTTON"
    }
  }
}

屏幕截图

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "screen/snapshot",
    "body": {
      "format": "png",
      "scale": 30
    }
  }
}

剪贴板

读取剪贴板

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "pasteboard/read"
  }
}

写入剪贴板

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "pasteboard/write",
    "body": {
      "uti": "public.plain-text",
      "data": "UTF8 文本或 Base64 图片"
    }
  }
}

词典/队列/脚本选择

设置词典值

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "proc-value/put",
    "body": {
      "key": "foo",
      "value": "bar"
    }
  }
}

推送队列

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "proc-queue/push",
    "body": {
      "key": "queue",
      "value": "item"
    }
  }
}

选中脚本

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1"],
    "type": "script/selected/put",
    "body": {
      "name": "demo.lua"
    }
  }
}

脚本控制

启动脚本

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1", "udid2"],
    "type": "script/run",
    "body": {
      "name": "脚本名称.lua" // 这里的 name 如果为 "" 表示启动设备端已经选中的脚本
    }
  }
}

停止脚本

{
  "ts": 1700000000,
  "nonce": "<nonce>",
  "sign": "hex-sign",
  "type": "control/command",
  "body": {
    "devices": ["udid1", "udid2"],
    "type": "script/stop"
  }
}

安全说明

  • 所有控制命令(WebSocket)与除绑定脚本下载外的 HTTP API 都需要使用 HMAC-SHA256 动态签名验证
  • 首次启动会生成随机密码(只显示一次),建议及时修改
  • 大文件建议使用 /api/transfer/* 走 HTTP 临时 token(WebSocket 仅适合小文件/控制消息)

About

用于 XXTouch 1.3.8+ 的云控服务端(WebSocket + 静态前端)与管理面板。

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors