Skip to main content

盒子内SDK API 开发文档

MYT-SDK API 接口文档

更新日期 2026-7-10

📌 接口说明

访问地址: http://{主机IP}:8000/swagger

  • 主机IP:设备的网络IP地址(例如:192.168.99.108)
  • 端口:固定为 8000
  • 协议:HTTP

响应格式:所有接口统一返回JSON格式

{
"code": 0,
"message": "ok",
"data": { ... }
}
字段类型说明
codeint状态码,0表示成功,非0表示失败
messagestring状态信息
dataobject返回数据

📚 接口目录

  1. 基本信息
  2. 云机操作
  3. 云机备份
  4. 终端连接
  5. myt_bridge网卡管理
  6. macVlan网卡管理
  7. 魔云腾VPC
  8. 本地机型数据管理
  9. 接口认证
  10. 服务管理
  11. 大模型管理
  12. 云机操作V2镜像
  13. 用户
  14. iSCSI磁盘管理
  15. RPA自动化
  16. M50管理
  17. 网盘
  18. 魔云腾VPN

一、基本信息

1. 获取API版本信息

功能说明:获取当前API版本信息

请求方式:GET

请求URL

http://{主机IP}:8000/info

请求参数:无

请求示例

curl "http://192.168.99.108:8000/info"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"latestVersion": 110,
"currentVersion": 108
}
}

返回字段说明

字段类型说明
latestVersionint线上最新版本号
currentVersionint当前本地版本号

失败返回

{
"code": 500,
"message": "获取版本信息失败",
"data": null
}

注意事项

  • 当 currentVersion < latestVersion 时,建议更新SDK

2. 获取设备基本信息

功能说明:获取当前设备的硬件和系统信息

请求方式:GET

请求URL

http://{主机IP}:8000/info/device

请求参数:无

请求示例

curl "http://192.168.99.108:8000/info/device"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"ip": "192.168.99.108",
"ip_1": "192.168.100.108",
"hwaddr": "AA:BB:CC:DD:EE:FF",
"hwaddr_1": "AA:BB:CC:DD:EE:F1",
"cputemp": 45,
"cpuload": "1.5",
"memtotal": "8GB",
"memuse": "4.2GB",
"mmctotal": "256GB",
"mmcuse": "120GB",
"version": "v1.1.0",
"deviceId": "MYT-P1-001",
"model": "P1",
"speed": "1000Mbps",
"mmcread": "150MB/s",
"mmcwrite": "120MB/s",
"sysuptime": "10天5小时",
"mmcmodel": "Samsung EVO",
"mmctemp": "38",
"network4g": "未连接",
"netWork_eth0": "已连接"
}
}

返回字段说明

字段类型说明
ipstring网口IP
ip_1string网口1的IP
hwaddrstringMAC地址
hwaddr_1stringMAC1地址
cputempintCPU温度
cpuloadstringCPU负载
memtotalstring内存总大小
memusestring内存已使用大小
mmctotalstring磁盘总大小
mmcusestring磁盘已使用大小
versionstring固件版本
deviceIdstring设备ID
modelstring型号版本
speedstring网口速率
mmcreadstring磁盘读取量
mmcwritestring磁盘写入量
sysuptimestring设备运行时间
mmcmodelstring磁盘型号
mmctempstring磁盘温度
network4gstring4G网卡状态
netWork_eth0stringETH0网卡状态

失败返回

{
"code": 500,
"message": "获取设备信息失败",
"data": null
}

3. 获取设备Agent信息

功能说明:获取当前设备Agent的安装状态、版本信息和配置详情

请求方式:GET

请求URL

http://{主机IP}:8000/info/agent

请求参数:无

请求示例

curl "http://192.168.99.108:8000/info/agent"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"installed": true,
"version": "1.0.0",
"status": "running",
"dashboard_port": 8080,
"profiles": [],
"kanban_enabled": true
}
}

返回字段说明

字段类型说明
installedbooleanAgent是否已安装
versionstringAgent版本号
statusstringAgent状态: running/stopped/unknown
dashboard_portintegerDashboard端口
profilesarrayProfile列表
kanban_enabledboolean是否启用Kanban

失败返回

{
"code": 500,
"message": "获取Agent信息失败",
"data": null
}

二、云机操作

1. 获取安卓云机列表

功能说明:获取设备上所有安卓云机容器列表

请求方式:GET

请求URL

http://{主机IP}:8000/android

请求参数

参数名必选类型说明
namestring根据云机名过滤
runningbool根据云机是否运行过滤,false查询所有
indexNumint根据云机实例位序号过滤(0-24)

请求示例

# 获取所有云机
curl "http://192.168.99.108:8000/android"

# 根据名称过滤
curl "http://192.168.99.108:8000/android?name=test"

# 只获取运行中的云机
curl "http://192.168.99.108:8000/android?running=true"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 2,
"list": [
{
"id": "abc123def456",
"name": "android-01",
"status": "running",
"indexNum": 1,
"dataPath": "/myt/data/android-01",
"modelPath": "/myt/model/android-01",
"image": "registry.example.com/android:v12",
"ip": "192.168.100.101",
"networkName": "myt_bridge",
"portBindings": {},
"dns": "223.5.5.5",
"doboxFps": "60",
"doboxWidth": "1080",
"doboxHeight": "1920",
"doboxDpi": "480",
"mgenable": "0",
"gmsenable": "0",
"s5User": "",
"s5Password": "",
"s5IP": "",
"s5Port": "",
"s5Type": "0",
"created": "2024-01-15 10:30:00",
"started": "2024-01-15 10:31:00",
"finished": "",
"customBinds": [],
"PINCode": ""
}
]
}
}

返回字段说明

字段类型说明
idstring云机容器ID
namestring云机名称
statusstring状态(running/stopped)
indexNumint云机实例位序号
dataPathstring云机Data文件在设备里的路径
modelPathstring云机机型文件在设备里的路径
imagestring云机所用的镜像
ipstring云机局域网IP
networkNamestring容器网卡名称
dnsstring云机DNS
doboxFpsstring云机FPS
doboxWidthstring云机分辨率的宽
doboxHeightstring云机分辨率的高
doboxDpistring云机DPI
mgenablestringmagisk开关,0-关,1-开
gmsenablestringgms开关,0-关,1-开
s5Userstrings5代理用户名
s5Passwordstrings5代理密码
s5IPstrings5代理IP
s5Portstrings5代理端口
s5Typestring代理类型,0-不开启,1-本地域名解析,2-服务器域名解析
createdstring云机容器创建时间
startedstring云机容器上次开启时间
finishedstring云机容器上次关闭时间
customBindsarray自定义文件映射
PINCodestring自定义屏幕锁屏密码

失败返回

{
"code": 500,
"message": "获取云机列表失败",
"data": null
}

2. 创建安卓云机

功能说明:创建一个新的安卓云机容器

请求方式:POST

请求URL

http://{主机IP}:8000/android

请求参数

参数名必选类型说明
namestring云机名称
imageUrlstring镜像完整地址
dnsstring云机DNS,例如223.5.5.5
modelIdstring线上机型ID
modelNamestring线上机型名称
LocalModelstring本地机型名称
modelStaticstring本地静态机型名称(优先级最高)
indexNumint实例序号,P1范围1-24,Q1范围1-12,传0自动分配
sandboxSizestring沙盒大小,例如16GB,32GB
offsetstring云机的开机时间
doboxFpsstring云机FPS
doboxWidthstring云机分辨率的宽
doboxHeightstring云机分辨率的高
doboxDpistring云机DPI
networkobject独立IP设置
startbool创建完成是否开机,默认true
mgenablestringmagisk开关,0-关,1-开,默认0
gmsenablestringgms开关,0-关,1-开,默认0
latitudefloat纬度
longitudefloat经度
countryCodestring国家代码,例如CN,US
portMappingsarray自定义端口映射
s5Userstrings5代理用户名
s5Passwordstrings5代理密码
s5IPstrings5代理IP
s5Portstrings5代理端口
s5Typestring代理类型,0-不开启,1-tun2socks,2-tun2proxy
mytBridgeNamestringmyt_bridge网卡名
customBindsarray自定义文件映射
PINCodestring屏幕锁屏密码,4-8位数字

network对象结构

字段类型说明
gwstring网关,例如192.168.100.1
ipstring云机要设置的IP
subnetstring掩码,例如192.168.100.0/24

portMappings数组元素结构

字段类型说明
containerPortint容器内端口
hostPortint主机端口
hostIPstring主机IP
protocolstring协议(tcp/udp),默认tcp

请求示例

curl -X POST "http://192.168.99.108:8000/android" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"imageUrl": "registry.example.com/android:v12",
"dns": "223.5.5.5",
"modelId": "1",
"indexNum": 1,
"doboxFps": "60",
"doboxWidth": "1080",
"doboxHeight": "1920",
"doboxDpi": "480",
"start": true
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"id": "abc123def456789"
}
}

失败返回

{
"code": 500,
"message": "创建云机失败: 镜像不存在",
"data": null
}

注意事项

  • name必须唯一,不能与已有云机重名
  • imageUrl必须是已拉取到本地的镜像地址
  • indexNum范围:P1设备1-24,Q1设备1-12
  • modelStatic优先级高于LocalModel和线上机型

3. 重置安卓云机

功能说明:重置指定的安卓云机

请求方式:PUT

请求URL

http://{主机IP}:8000/android

请求参数

参数名必选类型说明
namestring云机名称
latitudefloat纬度
longitudefloat经度
countryCodestring国家代码,例如CN,US

请求示例

curl -X PUT "http://192.168.99.108:8000/android" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"latitude": 39.9042,
"longitude": 116.4074,
"countryCode": "CN"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "重置云机失败: 云机不存在",
"data": null
}

注意事项

  • 重置会清除云机内的所有数据
  • 重置前请确保已备份重要数据

4. 删除安卓云机

功能说明:删除指定的安卓云机容器

请求方式:DELETE

请求URL

http://{主机IP}:8000/android

请求参数

参数名必选类型说明
namestring云机名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/android" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "删除云机失败: 云机正在运行",
"data": null
}

注意事项

  • 删除操作不可恢复
  • 建议删除前先停止云机

5. 切换安卓镜像

功能说明:切换云机使用的安卓镜像

请求方式:POST

请求URL

http://{主机IP}:8000/android/switchImage

请求参数

参数名必选类型说明
namestring云机名称
imageUrlstring镜像完整地址
adbPortint自定义adb端口,默认5555,设置端口0的时候不开启adb,请不要使用9082、9083、10000、10001、10006、10007、10008等端口
dnsstring云机DNS
enforceboolean安全模式,默认开启
gmsenablestringgms开关,0-关,1-开
macVlanIpstring独立IP设置
mgenablestringmagisk开关,0-关,1-开
mytBridgeNamestringmyt_bridge网卡名,可以接口查询或在设备终端使用ifconfig查询
portMappingsarray增加自定义端口映射
containerPortint容器内端口,如80
hostIPstring主机IP,如 0.0.0.0 或 不填
hostPortint主机端口,如8080
protocolstring协议,如 tcp、udp, 默认tcp
randomFileboolean随机系统文件名
startboolean创建完成开机,默认不开机
vpcIDinteger添加的魔云腾VPC节点ID
whiteListDnsarraydns白名单
customBindsarray自定义文件映射

请求示例

curl -X POST "http://192.168.99.108:8000/android/switchImage" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"imageUrl": "registry.example.com/android:v13",
"start": true
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"message": "镜像切换成功"
}
}

失败返回

{
"code": 500,
"message": "切换镜像失败: 镜像不存在",
"data": null
}

注意事项:

  • 切换镜像有风险,有概率无法开机,需要先备份

6. 切换机型

功能说明:切换云机的机型配置

请求方式:POST

请求URL

http://{主机IP}:8000/android/switchModel

请求参数

参数名必选类型说明
namestring云机名称
modelIdstring机型ID
localModelstring本地机型名称
modelStaticstring本地静态机型名称
latitudefloat纬度
longitudefloat经度
countryCodestring国家代码

请求示例

curl -X POST "http://192.168.99.108:8000/android/switchModel" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"modelId": "2",
"countryCode": "US"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "切换机型失败: 机型不存在",
"data": null
}

7. 拉取安卓镜像

功能说明:从镜像仓库拉取安卓镜像到本地

请求方式:POST

请求URL

http://{主机IP}:8000/android/pullImage

请求参数

参数名必选类型说明
imageUrlstring镜像完整地址

请求示例

curl -X POST "http://192.168.99.108:8000/android/pullImage" \
-H "Content-Type: application/json" \
-d '{
"imageUrl": "registry.example.com/android:v12"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "拉取镜像失败: 网络连接超时",
"data": null
}

注意事项

  • 拉取镜像可能需要较长时间,取决于网络速度和镜像大小
  • 确保设备有足够的磁盘空间

8. 启动安卓云机

功能说明:启动指定的安卓云机

请求方式:POST

请求URL

http://{主机IP}:8000/android/start

请求参数

参数名必选类型说明
namestring云机名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/start" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "启动云机失败: 云机已在运行",
"data": null
}

9. 关闭安卓云机

功能说明:关闭指定的安卓云机

请求方式:POST

请求URL

http://{主机IP}:8000/android/stop

请求参数

参数名必选类型说明
namestring云机名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/stop" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "关闭云机失败: 云机未运行",
"data": null
}

10. 重启安卓云机

功能说明:重启指定的安卓云机

请求方式:POST

请求URL

http://{主机IP}:8000/android/restart

请求参数

参数名必选类型说明
namestring云机名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/restart" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "重启云机失败",
"data": null
}

11. 获取本地镜像列表

功能说明:获取设备上已拉取的Docker镜像列表

请求方式:GET

请求URL

http://{主机IP}:8000/android/image

请求参数

参数名必选类型说明
imageNamestring根据镜像名过滤

请求示例

curl "http://192.168.99.108:8000/android/image"

# 根据名称过滤
curl "http://192.168.99.108:8000/android/image?imageName=android"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 2,
"list": [
{
"id": "sha256:abc123",
"imageUrl": "registry.example.com/android:v12",
"size": "2.5GB",
"created": "2024-01-10 08:00:00",
"labels": {
"version": "12",
"type": "android"
}
},
{
"id": "sha256:def456",
"imageUrl": "registry.example.com/android:v13",
"size": "2.8GB",
"created": "2024-01-15 10:00:00",
"labels": {
"version": "13",
"type": "android"
}
}
]
}
}

返回字段说明

字段类型说明
idstring镜像ID
imageUrlstring镜像完整地址
sizestring镜像大小
createdstring创建时间
labelsobject镜像labels

失败返回

{
"code": 500,
"message": "获取镜像列表失败",
"data": null
}

12. 删除本地镜像

功能说明:删除设备上的本地Docker镜像

请求方式:DELETE

请求URL

http://{主机IP}:8000/android/image

请求参数

参数名必选类型说明
imageUrlstring要删除的镜像完整地址

请求示例

curl -X DELETE "http://192.168.99.108:8000/android/image" \
-H "Content-Type: application/json" \
-d '{
"imageUrl": "registry.example.com/android:v12"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "删除镜像失败: 镜像正在被使用",
"data": null
}

注意事项

  • 正在被云机使用的镜像无法删除
  • 删除前请确保没有云机依赖该镜像

13. 获取本地镜像压缩包列表

功能说明:获取设备上的镜像压缩包文件列表

请求方式:GET

请求URL

http://{主机IP}:8000/android/imageTar

请求参数

参数名必选类型说明
filenamestring根据文件名过滤

请求示例

curl "http://192.168.99.108:8000/android/imageTar"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 2,
"list": [
{
"name": "android_v12.tar",
"size": "2.5GB"
},
{
"name": "android_v13.tar",
"size": "2.8GB"
}
]
}
}

失败返回

{
"code": 500,
"message": "获取镜像压缩包列表失败",
"data": null
}

14. 删除本地镜像压缩包

功能说明:删除设备上的镜像压缩包文件

请求方式:DELETE

请求URL

http://{主机IP}:8000/android/imageTar

请求参数

参数名必选类型说明
filenamestring要删除的镜像压缩包名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/android/imageTar" \
-H "Content-Type: application/json" \
-d '{
"filename": "android_v12.tar"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "删除镜像压缩包失败: 文件不存在",
"data": null
}

15. 导出安卓镜像

功能说明:将本地镜像导出为压缩包文件

请求方式:POST

请求URL

http://{主机IP}:8000/android/image/export

请求参数

参数名必选类型说明
imageUrlstring要导出的镜像完整地址

请求示例

curl -X POST "http://192.168.99.108:8000/android/image/export" \
-H "Content-Type: application/json" \
-d '{
"imageUrl": "registry.example.com/android:v12"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"filename": "android_v12_20240115.tar"
}
}

失败返回

{
"code": 500,
"message": "导出镜像失败: 磁盘空间不足",
"data": null
}

注意事项

  • 导出过程可能需要较长时间
  • 确保设备有足够的磁盘空间

16. 下载导出后的安卓镜像包

功能说明:下载已导出的镜像压缩包文件

请求方式:GET

请求URL

http://{主机IP}:8000/android/image/download

请求参数

参数名必选类型说明
filenamestring要下载的镜像包名

请求示例

curl "http://192.168.99.108:8000/android/image/download?filename=android_v12.tar" -o android_v12.tar

成功返回

  • 返回文件的二进制数据,浏览器会自动下载

失败返回

{
"code": 500,
"message": "下载失败: 文件不存在",
"data": null
}

17. 导入安卓镜像

功能说明:通过上传tar文件导入安卓镜像

请求方式:POST

请求URL

http://{主机IP}:8000/android/image/import

Content-Typemultipart/form-data

请求参数

参数名必选类型说明
filefile导入镜像包文件,tar格式

请求示例

curl -X POST "http://192.168.99.108:8000/android/image/import" \
-F "file=@android_v12.tar"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "导入镜像失败: 文件格式错误",
"data": null
}

注意事项

  • 仅支持tar格式的镜像包
  • 导入过程可能需要较长时间

18. 导出安卓云机

功能说明:将安卓云机导出为压缩包

请求方式:POST

请求URL

http://{主机IP}:8000/android/export

请求参数

参数名必选类型说明
namestring云机名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/export" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"exportName": "android-01_20240115.zip"
}
}

失败返回

{
"code": 500,
"message": "导出云机失败: 云机正在运行",
"data": null
}

注意事项

  • 建议导出前先停止云机
  • 导出文件包含云机的完整数据

19. 导入安卓云机

功能说明:通过上传文件导入安卓云机

请求方式:POST

请求URL

http://{主机IP}:8000/android/import

Content-Typemultipart/form-data

请求参数

参数名必选类型说明
filefile导入使用本SDK导出的安卓云机
indexNumint实例序号,P1范围1-24,Q1范围1-12
namestring导入后云机名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/import" \
-F "file=@android-01_20240115.zip" \
-F "indexNum=2" \
-F "name=android-02"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"name": "android-02"
}
}

失败返回

{
"code": 500,
"message": "导入云机失败: 实例位已被占用",
"data": null
}

注意事项

  • 仅支持本SDK导出的云机文件
  • indexNum不能与已有云机冲突

20. 获取机型列表

功能说明:获取线上可用的机型列表

请求方式:GET

请求URL

http://{主机IP}:8000/android/phoneModel

请求参数:无

请求示例

curl "http://192.168.99.108:8000/android/phoneModel"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"total": 50,
"list": [
{
"id": "1",
"name": "Samsung Galaxy S23",
"md5": "abc123def456",
"status": "active",
"currentVersion": 1,
"sdk_ver": "v1.1.0",
"createdAt": 1705286400
},
{
"id": "2",
"name": "Xiaomi 14",
"md5": "def456ghi789",
"status": "active",
"currentVersion": 1,
"sdk_ver": "v1.1.0",
"createdAt": 1705286400
}
]
}
}

返回字段说明

字段类型说明
idstring机型ID
namestring机型名称
md5string机型文件MD5
statusstring状态
currentVersionint当前版本
sdk_verstring对应SDK版本
createdAtint64创建时间戳

失败返回

{
"code": 500,
"message": "获取机型列表失败",
"data": null
}

21. 获取国家代码列表

功能说明:获取可用的国家代码列表

请求方式:GET

请求URL

http://{主机IP}:8000/android/countryCode

请求参数:无

请求示例

curl "http://192.168.99.108:8000/android/countryCode"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 200,
"list": [
{
"countryName": "中国",
"countryCode": "CN"
},
{
"countryName": "美国",
"countryCode": "US"
},
{
"countryName": "日本",
"countryCode": "JP"
}
]
}
}

失败返回

{
"code": 500,
"message": "获取国家代码列表失败",
"data": null
}

22. 设置Macvlan

功能说明:设置Macvlan网络配置

请求方式:POST

请求URL

http://{主机IP}:8000/android/macvlan

请求参数

参数名必选类型说明
gwstring网关,例如192.168.100.1
subnetstring掩码,例如192.168.100.0/24

请求示例

curl -X POST "http://192.168.99.108:8000/android/macvlan" \
-H "Content-Type: application/json" \
-d '{
"gw": "192.168.100.1",
"subnet": "192.168.100.0/24"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置Macvlan失败: 网关格式错误",
"data": null
}

注意事项

  • 设置后需要重启相关云机才能生效
  • 确保网关和子网配置正确

23. 设置云机容器IP (Macvlan模式)

功能说明:在Macvlan模式下设置云机容器的IP地址

请求方式:POST

请求URL

http://{主机IP}:8000/android/macvlan

请求参数

参数名必选类型说明
namestring云机名称
ipstring云机要设置的IP

请求示例

curl -X POST "http://192.168.99.108:8000/android/macvlan" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"ip": "192.168.100.101"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置IP失败: IP已被占用",
"data": null
}

24. 修改云机容器名称

功能说明:修改云机容器的名称

请求方式:POST

请求URL

http://{主机IP}:8000/android/rename

请求参数

参数名必选类型说明
namestring云机当前名称
newNamestring云机新名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/rename" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"newName": "my-android"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "修改名称失败: 新名称已存在",
"data": null
}

注意事项

  • 新名称不能与已有云机重名
  • 建议在云机停止状态下修改

25. 获取机型备份列表

功能说明:获取已备份的机型数据列表

请求方式:GET

请求URL

http://{主机IP}:8000/android/backup/model

请求参数:无

请求示例

curl "http://192.168.99.108:8000/android/backup/model"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 3,
"list": [
{
"name": "samsung_s23_backup"
},
{
"name": "xiaomi_14_backup"
}
]
}
}

失败返回

{
"code": 500,
"message": "获取机型备份列表失败",
"data": null
}

26. 删除机型备份

功能说明:删除指定的机型备份数据

请求方式:DELETE

请求URL

http://{主机IP}:8000/android/backup/model

请求参数

参数名必选类型说明
namestring机型备份文件名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/android/backup/model" \
-H "Content-Type: application/json" \
-d '{
"name": "samsung_s23_backup"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "删除机型备份失败: 文件不存在",
"data": null
}

27. 备份机型数据

功能说明:将V3镜像创建的云机里的机型数据完整备份

请求方式:POST

请求URL

http://{主机IP}:8000/android/backup/model

请求参数

参数名必选类型说明
namestring要备份机型数据的云机名称
suffixstring备份后机型数据的后缀名

请求示例

curl -X POST "http://192.168.99.108:8000/android/backup/model" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"suffix": "backup_20240115"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "备份机型数据失败: 云机不存在",
"data": null
}

注意事项

  • 仅支持V3镜像创建的云机
  • 备份前建议停止云机

28. 导出机型备份数据

功能说明:导出已备份的机型数据

请求方式:POST

请求URL

http://{主机IP}:8000/android/backup/modelExport

请求参数

参数名必选类型说明
namestring备份机型数据文件名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/backup/modelExport" \
-H "Content-Type: application/json" \
-d '{
"name": "samsung_s23_backup"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "导出机型备份失败: 文件不存在",
"data": null
}

29. 导入备份机型数据

功能说明:通过上传ZIP包导入备份的机型数据

请求方式:POST

请求URL

http://{主机IP}:8000/android/backup/modelImport

Content-Typemultipart/form-data

请求参数

参数名必选类型说明
filefile导入备份机型数据ZIP包

请求示例

curl -X POST "http://192.168.99.108:8000/android/backup/modelImport" \
-F "file=@samsung_s23_backup.zip"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "导入机型备份失败: 文件格式错误",
"data": null
}

注意事项

  • 仅支持ZIP格式的备份文件

30. 安卓云机执行命令

功能说明:在安卓云机内执行命令

请求方式:POST

请求URL

http://{主机IP}:8000/android/exec

请求参数

参数名必选类型说明
namestring云机名称
commandarray执行的命令,数组形式

请求示例

下载并安装小红书 APK
curl --location --request POST 'http://192.168.99.91:8000/android/exec' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'Host: 192.168.99.91:8000' \
--header 'Connection: keep-alive' \
--data-raw '{
"name": "3333333",
"command": ["sd", "-c", "curl -fsSL -o /sdcard/Download/xhs.apk https://redgray.xhscdn.com/ui/androidPublish/prod/xhs/channel/apk/9.17.0/9170809/v9170809-xhs-share_package_common_X64.apk && cp /sdcard/Download/xhs.apk /data/local/tmp/xhs.apk && pm install /data/local/tmp/xhs.apk && rm /data/local/tmp/xhs.apk"]
}'

成功返回

  Success

失败返回

{
"code": 500,
"message": "执行命令失败: 云机未运行",
"data": null
}

注意事项

  • 云机必须处于运行状态
  • command参数为数组格式,例如 ["sd", "-c", "ls -la"]

31. 清理所有未被使用镜像

功能说明:清理设备上所有未被云机使用的镜像

请求方式:POST

请求URL

http://{主机IP}:8000/android/pruneImages

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/android/pruneImages"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"pruneCount": 5,
"releaseSpace": "12.5GB"
}
}

返回字段说明

字段类型说明
pruneCountint清理数量
releaseSpacestring释放空间

失败返回

{
"code": 500,
"message": "清理镜像失败",
"data": null
}

注意事项

  • 此操作不可恢复
  • 仅清理未被任何云机使用的镜像

32. 批量切换容器镜像

功能说明:清理设备上所有未被云机使用的镜像

请求方式:POST

请求URL

http://{主机IP}:8000/android/change-image

请求参数

参数名必选类型说明
containerNamesarray云机容器名称列表
imagestring目标镜像完整地址

请求示例

curl http://192.168.99.108:8000/android/change-image \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"containerNames": [
"test-1", "test-2", "test-3"
],
"image": "registry.cn-guangzhou.aliyuncs.com/mytos/dobox:myt_supser_sdk_v1.0.14.30.36.1",
}'

成功返回

{
"code": 0,
"message": "OK",
"data": {
"taskId": "mdezt502491dgy413sp0hpf200goqkoa",
"message": "任务已提交,请使用 taskId 查询进度"
}
}

返回字段说明

字段类型说明
messagestring任务提交成功
taskIdstring任务ID

失败返回

{
"code": 51,
"message": "The image field is required",
"data": null
}

33. 复制云机

功能说明:复制指定云机的配置和数据,创建多个相同的云机实例

请求方式:GET

请求URL

http://{主机IP}:8000/android/copy

请求参数

参数名必选类型说明
namestring云机名称
indexNumint实例序号,P1范围1-24,Q1范围1-12,要复制到的目标实例号
countint复制的数量,一次最大20个

请求示例

GET "http://192.168.99.108:8000/android/copy?name=1772502684783_2_T0002&indexNum=6"
或者
curl 'curl 'http://192.168.99.108:8000/android/copy?name=1772502684783_2_T0002&indexNum=6'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 0,
"message": "ok",
"data": {}
}

34. 查询指定任务进度

功能说明:复制指定云机的配置和数据,创建多个相同的云机实例

请求方式:GET

请求URL

http://{主机IP}:8000/android/task-status

请求参数

参数名必选类型说明
taskIdstring任务 ID(异步任务返回的 taskId)

请求示例

GET "http://192.168.99.108:8000/android/copy?task-status?taskId=mdezt502491dgy413sp0hpf200goqkoa"
或者
curl 'http://192.168.99.183:8000/android/task-status?taskId=mdezt502491dgy413sp0hpf200goqkoa'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"taskId": "tmdezt502491dgy413sp0hpf200goqkoa",
"taskType": "change-image",
"progress": 80,
"status": "running",
"successCount": 2,
"failCount": 0,
"totalCount": 3,
"failDetail": [],
"createTime": "2026-03-09 16:30:00",
"updateTime": "2026-03-09 16:35:00"
}
}

失败返回

{
"code": 50,
"message": "任务不存在",
"data": null
}

35. 通过URL导入云机

功能说明:通过备份包直链地址导入安卓云机

请求方式:POST

请求URL

http://{主机IP}:8000/android/importByUrl

请求参数

参数名必选类型说明
urlstring备份包直链地址,仅支持http/https
indexNumint实例序号,P1范围1-24,Q1范围1-12
namestring导入后云机名称

请求示例

curl -X POST "http://192.168.99.108:8000/android/importByUrl" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/backups/android-01.zip",
"indexNum": 3,
"name": "android-imported"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"name": "android-imported"
}
}

失败返回

{
"code": 500,
"message": "导入云机失败: 网络连接超时",
"data": null
}

注意事项

  • 仅支持http/https协议的直链地址
  • indexNum不能与已有云机冲突

36. 导出安卓云机到共享存储

功能说明:将安卓云机导出到共享存储服务

请求方式:POST

请求URL

http://{主机IP}:8000/android/exportToOss

请求参数

参数名必选类型说明
namestring要导出的云机名称
ossUrlstring共享存储地址,例如https://oss.opencecs.com
bucketstring存储桶名称
filePathstring文件存储路径,不填则自动生成
accessKeystring访问密钥(private Bucket时必填)

请求示例

curl -X POST "http://192.168.99.108:8000/android/exportToOss" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"ossUrl": "https://oss.opencecs.com",
"bucket": "my-bucket",
"filePath": "backups/android-01.tar.gz"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"url": "http://192.168.1.100:8080/my-bucket/backups/android-01.tar.gz"
}
}

失败返回

{
"code": 500,
"message": "导出云机失败: OSS连接失败",
"data": null
}

注意事项

  • 建议导出前先停止云机
  • 确保OSS服务可用且bucket存在

37. 移动云机到指定实例位

功能说明:将指定云机移动到目标实例位

请求方式:POST

请求URL

http://{主机IP}:8000/android/move

请求参数

参数名必选类型说明
namestring云机名称
indexNuminteger目标实例序号,P1范围1-24,Q1范围1-12
startboolean移动完成后开机,默认不开机

请求示例

curl -X POST "http://192.168.99.108:8000/android/move" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"indexNum": 5,
"start": true
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "移动云机失败: 目标实例位已被占用",
"data": null
}

38. 批量安装APK到云机

功能说明:向多个云机批量安装 APK,支持多个 APK 下载地址,异步执行并返回任务ID

请求方式:POST

请求URL

http://{主机IP}:8000/android/batchInstallApk

请求参数

参数名必选类型说明
apkUrlsarrayAPK下载地址数组
containerNamesarray云机名数组

请求示例

curl -X POST "http://192.168.99.108:8000/android/batchInstallApk" \
-H "Content-Type: application/json" \
-d '{
"apkUrls": [
"https://example.com/app1.apk",
"https://example.com/app2.apk"
],
"containerNames": [
"android-01",
"android-02",
"android-03"
]
}'

成功返回

{
"code": 0,
"message": "OK",
"data": {
"taskId": "mdezt502491dgy413sp0hpf200goqkoa",
"message": "任务已提交,请使用 taskId 查询进度",
"total": 6
}
}

返回字段说明

字段类型说明
taskIdstring任务ID,用于查询安装进度
messagestring提示信息
totalint总安装次数 = APK数量 × 云机数量(apkUrls×containerNames)

失败返回

{
"code": 51,
"message": "The apkUrls field is required",
"data": null
}

注意事项

  • 任务为异步执行,请使用 /android/task-status 接口传入返回的 taskId 查询进度
  • total 为安装总次数,等于 APK 数量乘以云机数量

三、云机备份

1. 获取备份压缩包文件列表

功能说明:获取设备上的云机备份压缩包文件列表

请求方式:GET

请求URL

http://{主机IP}:8000/backup

请求参数

参数名必选类型说明
namestring根据文件名过滤

请求示例

curl "http://192.168.99.108:8000/backup"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 3,
"list": [
{
"name": "android-01_20240115.zip",
"size": "1.2GB"
},
{
"name": "android-02_20240116.zip",
"size": "1.5GB"
}
]
}
}

返回字段说明

字段类型说明
namestring备份压缩包文件名
sizestring备份压缩包大小

失败返回

{
"code": 500,
"message": "获取备份列表失败",
"data": null
}

2. 下载备份压缩包文件

功能说明:下载指定的云机备份压缩包

请求方式:GET

请求URL

http://{主机IP}:8000/backup/download

请求参数

参数名必选类型说明
namestring备份压缩包文件名

请求示例

GET "http://192.168.99.108:8000/backup/download?name=android-01_20240115.zip"

curl "http://192.168.99.108:8000/backup/download?name=android-01_20240115.zip" -o android-01_20240115.zip

成功返回

  • 返回文件的二进制数据,浏览器会自动下载

失败返回

{
"code": 500,
"message": "下载失败: 文件不存在",
"data": null
}

3. 删除备份压缩包文件

功能说明:删除指定的云机备份压缩包

请求方式:DELETE

请求URL

http://{主机IP}:8000/backup

请求参数

参数名必选类型说明
namestring备份压缩包文件名

请求示例

curl -X DELETE "http://192.168.99.108:8000/backup" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01_20240115.zip"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "删除备份失败: 文件不存在",
"data": null
}

四、终端连接

1. 连接设备SSH

1.1. 接口概述

功能: 通过 WebSocket 在浏览器中连接到设备的 SSH 终端

协议: WebSocket (基于 HTTP Upgrade)

端点: ws://{host}:8000/link/sshwss://{host}:8000/link/ssh

认证: 需要 HTTP Basic Auth (与其他 myt-sdk API 相同)

适用场景:

  • Web 界面直接 SSH 到设备 (ARM 板、服务器等)
  • 无需本地 SSH 客户端
  • 云手机平台的设备运维和调试

与容器终端的区别:

  • 容器终端 (/link/exec): 连接到 Docker 容器内部
  • 设备 SSH (/link/ssh): 连接到宿主机或远程设备的 SSH 服务

1.2. 连接建立

1.2.1 WebSocket 握手
// 前端示例
const wsUrl =
(location.protocol === "https:" ? "wss://" : "ws://") +
location.host +
"/link/ssh";

const socket = new WebSocket(wsUrl);
socket.binaryType = "arraybuffer"; // 重要:设置为二进制模式

socket.onopen = () => {
console.log("WebSocket 连接已建立");
};

socket.onmessage = (event) => {
// SSH 输出始终是二进制数据
if (event.data instanceof ArrayBuffer) {
const bytes = new Uint8Array(event.data);
// 传递给终端模拟器渲染
terminal.write(bytes);
} else {
// 文本消息 (错误提示)
console.log("服务端消息:", event.data);
}
};

socket.onerror = (error) => {
console.error("WebSocket 错误:", error);
};

socket.onclose = () => {
console.log("WebSocket 连接已关闭");
};
1.2.2 认证方式

两层认证:

  1. WebSocket 层认证: HTTP Basic Auth (访问 myt-sdk API)
  2. SSH 层认证: 用户名 + 密码 (登录目标设备)
// WebSocket 层认证 (同域下自动携带 Cookie)
// 如果跨域,需要在 URL 中携带凭证或通过代理

// SSH 层认证 (通过 login 消息发送)
socket.send(
JSON.stringify({
type: "login",
ip: "192.168.1.100",
port: 22,
user: "root",
password: "your_password",
}),
);

1.3. 消息协议

1.3.1 消息格式

所有客户端发送的消息均为 JSON 文本格式:

{
"type": "消息类型",
"...": "其他字段"
}

服务端返回的消息分为两种:

  • 二进制消息: SSH 终端的输出 (stdout/stderr)
  • 文本消息: 错误提示或状态信息
1.3.2 消息类型详解
1.3.2.1 login - SSH 登录

方向: 客户端 → 服务端

时机: WebSocket 连接建立后立即发送

字段:

字段类型必填说明
typestring固定值 "login"
ipstring目标设备 IP 地址
portintSSH 端口 (通常为 22)
userstringSSH 用户名(默认user)
passwordstringSSH 密码(默认myt)

示例:

{
"type": "login",
"ip": "192.168.1.100",
"port": 22,
"user": "root",
"password": "mypassword"
}

说明:

  • ip 可以是 IPv4 地址、IPv6 地址或域名
  • port 默认 SSH 端口为 22,如果设备使用自定义端口需指定
  • 认证方式仅支持密码认证,不支持密钥认证
  • SSH 连接超时时间为 5 秒

错误响应示例:

SSH连接失败: dial tcp 192.168.1.100:22: i/o timeout
SSH连接失败: ssh: handshake failed: ssh: unable to authenticate
创建Session失败
RequestPty 失败
启动 Shell 失败

成功响应示例:

成功连接到 192.168.1.100:22
1.3.2.2 stdin - 用户输入

方向: 客户端 → 服务端

时机: 用户在终端中输入字符时

字段:

字段类型必填说明
typestring固定值 "stdin"
datastring用户输入的数据 (包括控制字符)

示例:

{
"type": "stdin",
"data": "ls -la\r"
}

说明:

  • data 包含原始按键数据,包括:
    • 普通字符: a, b, 1, 2
    • 回车: \r\n
    • 退格: \x7f (DEL) 或 \x08 (BS)
    • 方向键: \x1b[A (上), \x1b[B (下), \x1b[C (右), \x1b[D (左)
    • Ctrl+C: \x03
    • Ctrl+D: \x04
  • 数据会直接写入 SSH 会话的 stdin
1.3.2.3 resize - 调整终端大小

方向: 客户端 → 服务端

时机: 浏览器窗口大小变化时

字段:

字段类型必填说明
typestring固定值 "resize"
colsint终端列数 (宽度)
rowsint终端行数 (高度)

示例:

{
"type": "resize",
"cols": 120,
"rows": 30
}

说明:

  • 必须在 login 成功后发送
  • 如果不发送 resize,SSH 终端会使用默认大小 (80x40)
  • 终端大小不匹配会导致显示错乱 (如 vim 编辑器)
1.3.2.4 heartbeat - 保活心跳

方向: 客户端 → 服务端

时机: 定期发送 (建议 30 秒间隔)

字段:

字段类型必填说明
typestring固定值 "heartbeat"

示例:

{
"type": "heartbeat"
}

说明:

  • 防止 WebSocket 连接因空闲超时被中间代理关闭
  • 服务端收到后不做任何响应,仅保持连接活跃
1.3.3 服务端响应
1.3.3.1 SSH 输出 (二进制消息)

方向: 服务端 → 客户端

格式: WebSocket Binary Frame

内容: SSH stdout/stderr 的原始字节流

示例 (伪代码):

socket.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
// 二进制数据 - SSH 输出
const bytes = new Uint8Array(event.data);
// 传递给 xterm.js 渲染
terminal.write(bytes);
}
};

说明:

  • 包含 ANSI 转义序列 (颜色、光标控制等)
  • 需要使用终端模拟器 (如 xterm.js) 正确渲染
  • 服务端启用了括号粘贴模式 (Bracketed Paste Mode),输出中会包含 \x1b[?2004h (启用) 和 \x1b[?2004l (关闭) 转义序列。xterm.js 默认支持此模式,无需额外处理。如果使用自定义终端渲染器,需正确解析这些序列以避免显示异常
1.3.3.2 错误消息 (文本消息)

方向: 服务端 → 客户端

格式: WebSocket Text Frame

内容: 错误描述字符串 (带 ANSI 颜色代码)

示例:

\r\n\x1b[31mSSH连接失败: dial tcp 192.168.1.100:22: connection refused\x1b[0m\r\n
\r\n\x1b[32m成功连接到 192.168.1.100:22\x1b[0m\r\n

说明:

  • 错误消息使用红色 (\x1b[31m)
  • 成功消息不含 ANSI 颜色码,为纯文本 (实测验证: 返回 "成功连接到 127.0.0.1:22\n" 无任何转义序列)
  • 消息末尾有 \\x1b[0m 重置颜色 (仅错误消息)

1.4. 完整交互流程

客户端                                服务端
| |
|--- WebSocket Upgrade -------------->|
|<-- 101 Switching Protocols ---------|
| |
|--- {"type":"login",...} ----------->| 建立 SSH 连接
| | 创建 SSH Session
| | 请求 PTY (xterm)
| | 启动 Shell
|<-- Text: "成功连接到 192..." -------|
|<-- Binary: "user@host:~$ " ---------|
| |
|--- {"type":"resize",...} ---------->| 调整 PTY 大小
| |
|--- {"type":"stdin","data":"ls\r"} ->| 写入 SSH stdin
|<-- Binary: "file1\nfile2\n..." ----|
| |
|--- {"type":"heartbeat"} ----------->| (无响应)
| |
|--- {"type":"stdin","data":"exit\r"}>| SSH 会话退出
|<-- Binary: "logout\n" --------------|
|<-- WebSocket Close -----------------|
| |

1.5. 前端集成示例

1.5.1 使用 xterm.js (完整示例)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Web SSH Terminal</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css"
/>
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
<style>
body {
margin: 0;
padding: 20px;
background: #0c0c0c;
}
#terminal {
width: 100%;
height: 600px;
}
#login-form {
background: #1e1e1e;
padding: 20px;
border-radius: 8px;
max-width: 400px;
margin: 50px auto;
color: #fff;
}
input {
width: 100%;
padding: 8px;
margin: 5px 0 15px;
border: 1px solid #444;
background: #2d2d2d;
color: #fff;
border-radius: 4px;
}
button {
width: 100%;
padding: 10px;
background: #0078d4;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #005a9e;
}
</style>
</head>
<body>
<!-- 登录表单 -->
<div id="login-form">
<h2>SSH 连接</h2>
<label>IP 地址:</label>
<input type="text" id="ip" value="127.0.0.1" />

<label>端口:</label>
<input type="number" id="port" value="22" />

<label>用户名:</label>
<input type="text" id="user" value="root" />

<label>密码:</label>
<input type="password" id="password" />

<button onclick="connect()">连接</button>
</div>

<!-- 终端容器 -->
<div id="terminal" style="display:none;"></div>

<script>
let term, fitAddon, socket, heartbeatTimer;

function connect() {
const ip = document.getElementById("ip").value;
const port = parseInt(document.getElementById("port").value);
const user = document.getElementById("user").value;
const password = document.getElementById("password").value;

if (!ip || !user || !password) {
alert("请填写完整信息");
return;
}

// 隐藏登录表单,显示终端
document.getElementById("login-form").style.display = "none";
document.getElementById("terminal").style.display = "block";

// 初始化终端
term = new Terminal({
cursorBlink: true,
fontSize: 14,
fontFamily: 'Consolas, "Courier New", monospace',
theme: { background: "#0c0c0c" },
});
fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(document.getElementById("terminal"));
fitAddon.fit();
term.focus();

// 连接 WebSocket
const wsUrl = `ws://${location.host}/link/ssh`;
//将${location.host}替换成直接要连接的设备IP和端口,例如:const wsUrl = `ws://10.10.11.4:8000/link/ssh`;
socket = new WebSocket(wsUrl);
socket.binaryType = "arraybuffer";

socket.onopen = () => {
term.write("\r\n\x1b[32m正在建立连接...\x1b[0m\r\n");

// 发送登录认证
socket.send(
JSON.stringify({
type: "login",
ip: ip,
port: port,
user: user,
password: password,
}),
);

// 发送终端大小
const dims = fitAddon.proposeDimensions();
socket.send(
JSON.stringify({
type: "resize",
cols: dims.cols,
rows: dims.rows,
}),
);

// 启动心跳
heartbeatTimer = setInterval(() => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ type: "heartbeat" }));
}
}, 30000);
};

socket.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
// 二进制数据 - SSH 输出
term.write(new Uint8Array(event.data));
} else {
// 文本消息 - 错误或状态
term.write(event.data);
}
};

socket.onerror = () => {
term.write("\r\n\x1b[31mSocket 连接错误\x1b[0m\r\n");
};

socket.onclose = () => {
term.write("\r\n\x1b[31m连接已断开, 请刷新页面重试\x1b[0m\r\n");
clearInterval(heartbeatTimer);
};

// 用户输入 → WebSocket
term.onData((data) => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ type: "stdin", data: data }));
}
});

// 窗口大小变化 → WebSocket
window.addEventListener("resize", () => {
fitAddon.fit();
const dims = fitAddon.proposeDimensions();
if (socket.readyState === WebSocket.OPEN) {
socket.send(
JSON.stringify({
type: "resize",
cols: dims.cols,
rows: dims.rows,
}),
);
}
});
}
</script>
</body>
</html>
1.5.2 使用原生 WebSocket (无终端模拟器)
const socket = new WebSocket("ws://192.168.1.100:8000/link/ssh");
socket.binaryType = "arraybuffer";

socket.onopen = () => {
// 登录
socket.send(
JSON.stringify({
type: "login",
ip: "127.0.0.1",
port: 22,
user: "root",
password: "mypassword",
}),
);

// 设置终端大小
socket.send(
JSON.stringify({
type: "resize",
cols: 80,
rows: 24,
}),
);

// 执行命令
setTimeout(() => {
socket.send(
JSON.stringify({
type: "stdin",
data: "uname -a\r",
}),
);
}, 1000);

setTimeout(() => {
socket.send(
JSON.stringify({
type: "stdin",
data: "exit\r",
}),
);
}, 3000);
};

socket.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
// 二进制数据 - SSH 输出
const text = new TextDecoder().decode(event.data);
console.log("输出:", text);
} else {
// 文本消息 - 错误或状态
console.log("消息:", event.data);
}
};

示例图:连接ssh01

连接ssh02

1.6. 后端实现细节

1.6.1 技术栈
  • Web 框架: GoFrame v2
  • WebSocket: gorilla/websocket
  • SSH 客户端: golang.org/x/crypto/ssh
1.6.2 关键实现
// 1. 升级 HTTP 为 WebSocket
ws, err := wsUpGrader.Upgrade(r.Response.Writer, r.Request, nil)

// 2. 建立 SSH 连接
config := &ssh.ClientConfig{
User: msg.User,
Auth: []ssh.AuthMethod{
ssh.Password(msg.Password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 生产环境应验证 host key
Timeout: 5 * time.Second,
}
addr := fmt.Sprintf("%s:%d", msg.Ip, msg.Port)
sshClient, err := ssh.Dial("tcp", addr, config)

// 3. 创建 SSH Session
session, err := sshClient.NewSession()

// 4. 请求伪终端 (PTY)
modes := ssh.TerminalModes{
ssh.ECHO: 1,
}
session.RequestPty("xterm", 40, 80, modes)

// 5. 重定向 SSH 输出到 WebSocket
type WebSocketWriter struct {
ws *websocket.Conn
}
func (w *WebSocketWriter) Write(p []byte) (n int, err error) {
err = w.ws.WriteMessage(websocket.BinaryMessage, p)
if err != nil { return 0, err }
return len(p), nil
}

session.Stdout = &WebSocketWriter{ws: ws}
session.Stderr = &WebSocketWriter{ws: ws}

// 6. 启动 Shell
session.Shell()

// 7. 双向转发
// WebSocket 输入 → SSH stdin
sshStdin, _ := session.StdinPipe()
for {
_, msgBytes, err := ws.ReadMessage()
if err != nil { break }

var msg WsMsg
json.Unmarshal(msgBytes, &msg)

switch msg.Type {
case "stdin":
sshStdin.Write([]byte(msg.Data))
case "resize":
session.WindowChange(msg.Rows, msg.Cols)
}
}

// 8. 等待 Shell 退出
go func() {
session.Wait()
ws.Close()
}()

1.7. 常见问题

1.7.1 SSH 连接失败

问题: 收到 "SSH连接失败" 错误

可能原因:

  • 目标设备 SSH 服务未启动
  • IP 地址或端口错误
  • 网络不可达 (防火墙、路由问题)
  • 用户名或密码错误

解决:

  • 确认目标设备 SSH 服务运行: systemctl status sshd
  • 测试网络连通性: ping <ip>telnet <ip> 22
  • 验证用户名密码: ssh user@ip
1.7.2 终端显示乱码

问题: 终端显示乱码或控制字符

原因:

  • 未使用终端模拟器渲染 ANSI 转义序列
  • 终端大小未正确设置
  • 字符编码不匹配

解决:

  • 使用 xterm.js 等终端模拟器
  • login 后立即发送 resize 消息
  • 确保 WebSocket 设置为 binaryType = 'arraybuffer'
1.7.3 连接意外断开

问题: WebSocket 连接在空闲时自动关闭

原因:

  • 中间代理 (Nginx/负载均衡器) 超时
  • SSH 服务器超时断开
  • 网络不稳定

解决:

  • 定期发送 heartbeat 消息 (建议 30 秒)
  • 配置代理服务器的 WebSocket 超时时间
  • 配置 SSH 服务器的 ClientAliveIntervalClientAliveCountMax
1.7.4 无法执行交互式命令

问题: vim, top, htop 等命令显示异常

原因:

  • 终端大小未设置或不匹配
  • 未分配伪终端 (PTY)

解决:

  • 确保发送了正确的 resize 消息
  • 后端必须调用 session.RequestPty() (已默认启用)
1.7.5 密码认证失败

问题: 收到 "ssh: unable to authenticate" 错误

可能原因:

  • 密码错误
  • SSH 服务器禁用了密码认证 (仅允许密钥认证)
  • 用户账户被锁定

解决:

  • 验证密码正确性
  • 检查 SSH 服务器配置: /etc/ssh/sshd_configPasswordAuthentication 应为 yes
  • 检查用户账户状态: passwd -S <user>

1.8. 安全建议

1.8.1 传输安全
  1. 启用 HTTPS/WSS: 生产环境必须使用加密连接,防止密码明文传输
  2. 证书验证: 后端应验证 SSH 服务器的 host key,避免中间人攻击
    // 生产环境应替换 InsecureIgnoreHostKey
    HostKeyCallback: ssh.FixedHostKey(hostKey)
1.8.2 认证鉴权
  1. 双层认证: WebSocket 层 + SSH 层
  2. 密码存储: 前端不应缓存 SSH 密码,每次连接重新输入
  3. 会话超时: 设置最大空闲时间 (如 30 分钟)
1.8.3 访问控制
  1. IP 白名单: 限制可连接的目标 IP 范围
  2. 用户隔离: 限制用户只能 SSH 到自己的设备
  3. 审计日志: 记录所有 SSH 连接和命令执行
1.8.4 防护措施
  1. 连接限制: 限制单个用户的并发 SSH 连接数
  2. 速率限制: 防止暴力破解密码
  3. 命令过滤: 可选地拦截危险命令 (如 rm -rf /)

1.9. 性能优化

  1. 连接池: 复用 SSH 连接 (需要修改后端实现)
  2. 心跳间隔: 30 秒是推荐值,过短会增加网络开销
  3. 缓冲区大小: 后端使用 4KB 缓冲区,适合大多数场景
  4. 资源清理: 连接断开时自动清理 SSH 会话

1.10. 与容器终端的对比

特性设备 SSH (/link/ssh)容器终端 (/link/exec)
连接目标远程设备 SSH 服务Docker 容器内部
认证方式SSH 用户名+密码容器 ID/名称
网络要求需要网络可达目标设备本地 Docker API
权限取决于 SSH 用户权限容器内 root 权限
适用场景设备运维、远程管理容器调试、应用排查
login 参数ip, port, user, passwordcontainer_id, shell

11. 参考资源

附录: 完整消息类型定义

// TypeScript 类型定义
interface WsMsg {
type: "login" | "stdin" | "resize" | "heartbeat";

// login 字段
ip?: string;
port?: number;
user?: string;
password?: string;

// stdin 字段
data?: string;

// resize 字段
cols?: number;
rows?: number;
}

// 使用示例
const loginMsg: WsMsg = {
type: "login",
ip: "192.168.1.100",
port: 22,
user: "root",
password: "mypassword",
};

const stdinMsg: WsMsg = {
type: "stdin",
data: "ls -la\r",
};

const resizeMsg: WsMsg = {
type: "resize",
cols: 120,
rows: 30,
};

const heartbeatMsg: WsMsg = {
type: "heartbeat",
};

附录: 错误码参考

错误消息原因解决方案
dial tcp ... i/o timeout网络不可达或防火墙阻止检查网络连通性和防火墙规则
connection refusedSSH 服务未启动启动 SSH 服务: systemctl start sshd
ssh: unable to authenticate密码错误或认证方式不支持验证密码,检查 SSH 配置
创建Session失败SSH 连接建立后无法创建会话检查 SSH 服务器资源和配置
RequestPty 失败无法分配伪终端检查 SSH 服务器 PTY 配置
启动 Shell 失败无法启动 Shell 进程检查用户 Shell 配置 (/etc/passwd)

2. 修改SSH登录用户密码

功能说明:修改SSH登录用户的密码

请求方式:POST

请求URL

http://{主机IP}:8000/link/ssh/changePwd

请求参数

参数名必选类型说明
usernamestring用户名,默认user
passwordstring新密码

请求示例

curl -X POST "http://192.168.99.108:8000/link/ssh/changePwd" \
-H "Content-Type: application/json" \
-d '{
"username": "user",
"password": "newpassword123"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "修改密码失败",
"data": null
}

注意事项

  • 密码修改后立即生效
  • 请牢记新密码

3. 开关SSH root登录

功能说明:启用或禁止SSH root用户登录

请求方式:POST

请求URL

http://{主机IP}:8000/link/ssh/switchRoot

请求参数

参数名必选类型说明
enablebooltrue-启用root登录,false-禁止root登录

请求示例

curl -X POST "http://192.168.99.108:8000/link/ssh/switchRoot" \
-H "Content-Type: application/json" \
-d '{
"enable": true
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置失败",
"data": null
}

注意事项

  • 出于安全考虑,建议禁用root登录

4. 开关SSH服务

功能说明:启用或关闭SSH服务

请求方式:POST

请求URL

http://{主机IP}:8000/link/ssh/enable

请求参数

参数名必选类型说明
enablebooltrue-启用ssh服务,false-关闭ssh服务

请求示例

curl -X POST "http://192.168.99.108:8000/link/ssh/enable" \
-H "Content-Type: application/json" \
-d '{
"enable": true
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置SSH服务失败",
"data": null
}

5. 连接容器终端

5.1. 接口概述

功能: 通过 WebSocket 在浏览器中连接到 Docker 容器的交互式终端

协议: WebSocket (基于 HTTP Upgrade)

端点: ws://{host}:8000/link/execwss://{host}:8000/link/exec

认证: 需要 HTTP Basic Auth (与其他 myt-sdk API 相同)

适用场景:

  • Web 界面直接操作容器内部
  • 无需 SSH 或 docker exec 命令
  • 云手机平台的容器调试和运维

5.2. 连接建立

5.2.1 WebSocket 握手
// 前端示例
const wsUrl =
(location.protocol === "https:" ? "wss://" : "ws://") +
location.host +
"/link/exec";

const socket = new WebSocket(wsUrl);

socket.onopen = () => {
console.log("WebSocket 连接已建立");
};

socket.onmessage = (event) => {
// event.data 可能是文本或二进制数据
if (typeof event.data === "string") {
console.log("收到文本:", event.data);
} else {
// 二进制数据 (容器输出)
const arrayBuffer = event.data;
}
};

socket.onerror = (error) => {
console.error("WebSocket 错误:", error);
};

socket.onclose = () => {
console.log("WebSocket 连接已关闭");
};
5.2.2 认证方式

如果 myt-sdk 启用了 Basic Auth,需要在 WebSocket URL 中携带凭证:

// 方式1: URL 中携带 (不推荐,凭证会暴露在 URL)
const wsUrl = `ws://username:password@${host}:8000/link/exec`;

// 方式2: 通过 HTTP 请求头 (推荐)
// 注意:浏览器 WebSocket API 不支持自定义请求头
// 需要先通过 HTTP 请求获取 session/token,或使用代理服务器

推荐方案: 在同域下先通过普通 HTTP 请求完成认证,浏览器会自动携带 Cookie

5.3. 消息协议

5.3.1 消息格式

所有客户端发送的消息均为 JSON 文本格式:

{
"type": "消息类型",
"...": "其他字段"
}

服务端返回的消息分为两种:

  • 文本消息: 错误提示或状态信息
  • 二进制消息: 容器终端的输出 (stdout/stderr)
5.3.2 消息类型详解
5.3.2.1 login - 初始化连接

方向: 客户端 → 服务端

时机: WebSocket 连接建立后立即发送

字段:

字段类型必填说明
typestring固定值 "login"
container_idstring容器 ID 或容器名称
shellstringShell 路径,默认 /bin/sh

示例:

{
"type": "login",
"container_id": "android_slot_0",
"shell": "/bin/bash"
}

说明:

  • container_id 可以是完整的容器 ID (64位十六进制) 或容器名称
  • shell 可选值: /bin/bash, /bin/sh, /bin/zsh 等 (取决于容器内安装的 shell)
  • 如果容器不存在或无法连接,服务端会返回错误文本消息

错误响应示例:

Docker Client Init Error: Cannot connect to the Docker daemon
Exec Create Error: No such container: android_slot_0
Exec Attach Error: container is not running
5.3.2.2 stdin - 用户输入

方向: 客户端 → 服务端

时机: 用户在终端中输入字符时

字段:

字段类型必填说明
typestring固定值 "stdin"
datastring用户输入的数据 (包括控制字符)

示例:

{
"type": "stdin",
"data": "ls -la\r"
}

说明:

  • data 包含原始按键数据,包括:
    • 普通字符: a, b, 1, 2
    • 回车: \r\n
    • 退格: \x7f (DEL) 或 \x08 (BS)
    • 方向键: \x1b[A (上), \x1b[B (下), \x1b[C (右), \x1b[D (左)
    • Ctrl+C: \x03
    • Ctrl+D: \x04
  • 数据会直接写入容器的 stdin
5.3.2.3 resize - 调整终端大小

方向: 客户端 → 服务端

时机: 浏览器窗口大小变化时

字段:

字段类型必填说明
typestring固定值 "resize"
colsint终端列数 (宽度)
rowsint终端行数 (高度)

示例:

{
"type": "resize",
"cols": 120,
"rows": 30
}

说明:

  • 必须在 login 成功后发送
  • 如果不发送 resize,容器终端会使用默认大小 (通常是 80x24)
  • 终端大小不匹配会导致显示错乱 (如 vim 编辑器)
5.3.2.4 heartbeat - 保活心跳

方向: 客户端 → 服务端

时机: 定期发送 (建议 30 秒间隔)

字段:

字段类型必填说明
typestring固定值 "heartbeat"

示例:

{
"type": "heartbeat"
}

说明:

  • 防止 WebSocket 连接因空闲超时被中间代理关闭
  • 服务端收到后不做任何响应,仅保持连接活跃
5.3.3 服务端响应
5.3.3.1 容器输出 (二进制消息)

方向: 服务端 → 客户端

格式: WebSocket Binary Frame

内容: 容器 stdout/stderr 的原始字节流

示例 (伪代码):

socket.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
// 二进制数据 - 容器输出
const bytes = new Uint8Array(event.data);
// 传递给 xterm.js 渲染
terminal.write(bytes);
}
};

说明:

  • 包含 ANSI 转义序列 (颜色、光标控制等)
  • 需要使用终端模拟器 (如 xterm.js) 正确渲染
5.3.3.2 错误消息 (文本消息)

方向: 服务端 → 客户端

格式: WebSocket Text Frame

内容: 错误描述字符串

示例:

Docker Client Init Error: Cannot connect to the Docker daemon at unix:///var/run/docker.sock
Exec Create Error: No such container: invalid_container_id
Exec Attach Error: container is not running

说明:

  • 仅在连接初始化失败时发送
  • 收到错误消息后,WebSocket 连接会被服务端关闭

5.4. 完整交互流程

客户端                                服务端
| |
|--- WebSocket Upgrade -------------->|
|<-- 101 Switching Protocols ---------|
| |
|--- {"type":"login",...} ----------->| 创建 Docker Exec
| | 劫持容器 stdin/stdout
|<-- Binary: "root@container:~# " ---|
| |
|--- {"type":"resize",...} ---------->| 调整终端大小
| |
|--- {"type":"stdin","data":"ls\r"} ->| 写入容器 stdin
|<-- Binary: "file1\nfile2\n..." ----|
| |
|--- {"type":"heartbeat"} ----------->| (无响应)
| |
|--- {"type":"stdin","data":"exit\r"}>| 容器进程退出
|<-- Binary: "logout\n" --------------|
|<-- WebSocket Close -----------------|
| |

5.5. 前端集成示例

5.5.1 使用 xterm.js
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css"
/>
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
</head>
<body>
<div id="terminal"></div>

<script>
const term = new Terminal({
cursorBlink: true,
fontSize: 14,
fontFamily: 'Consolas, "Courier New", monospace',
});
const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(document.getElementById("terminal"));
fitAddon.fit();

// 连接 WebSocket
const wsUrl = `ws://${location.host}/link/exec`;
//location.host替换成自己的设备IP,端口固定为8000,例如:10.10.11.4:8000
const socket = new WebSocket(wsUrl);

socket.onopen = () => {
// 发送 login 消息
socket.send(
JSON.stringify({
type: "login",
//"android_slot_0"替换成容器id或名称,例如:1777544648515_1_T0001
container_id: "android_slot_0",
shell: "/bin/sh",
}),
);

// 发送初始终端大小
const dims = fitAddon.proposeDimensions();
socket.send(
JSON.stringify({
type: "resize",
cols: dims.cols,
rows: dims.rows,
}),
);

// 启动心跳
setInterval(() => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ type: "heartbeat" }));
}
}, 30000);
};

socket.onmessage = (event) => {
if (typeof event.data === "string") {
// 错误消息
term.write("\r\n\x1b[31m" + event.data + "\x1b[0m\r\n");
} else {
// 容器输出
const reader = new FileReader();
reader.onload = () => {
term.write(new Uint8Array(reader.result));
};
reader.readAsArrayBuffer(event.data);
}
};

socket.onerror = (error) => {
term.write("\r\n\x1b[31mWebSocket Error\x1b[0m\r\n");
};

socket.onclose = () => {
term.write("\r\n\x1b[33mConnection Closed\x1b[0m\r\n");
};

// 用户输入 → WebSocket
term.onData((data) => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ type: "stdin", data: data }));
}
});

// 窗口大小变化 → WebSocket
window.addEventListener("resize", () => {
fitAddon.fit();
const dims = fitAddon.proposeDimensions();
if (socket.readyState === WebSocket.OPEN) {
socket.send(
JSON.stringify({
type: "resize",
cols: dims.cols,
rows: dims.rows,
}),
);
}
});
</script>
</body>
</html>
5.5.2 使用原生 WebSocket (无终端模拟器)
const socket = new WebSocket("ws://192.168.1.100:8000/link/exec");

socket.onopen = () => {
// 登录
socket.send(
JSON.stringify({
type: "login",
container_id: "my_container",
shell: "/bin/sh",
}),
);

// 设置终端大小
socket.send(
JSON.stringify({
type: "resize",
cols: 80,
rows: 24,
}),
);

// 执行命令
setTimeout(() => {
socket.send(
JSON.stringify({
type: "stdin",
data: "uname -a\r",
}),
);
}, 1000);

setTimeout(() => {
socket.send(
JSON.stringify({
type: "stdin",
data: "exit\r",
}),
);
}, 3000);
};

socket.onmessage = (event) => {
if (typeof event.data === "string") {
console.log("错误:", event.data);
} else {
// 二进制数据
const reader = new FileReader();
reader.onload = () => {
const text = new TextDecoder().decode(reader.result);
console.log("输出:", text);
};
reader.readAsArrayBuffer(event.data);
}
};

示例图:连接终端

5.6. 后端实现细节

5.6.1 技术栈
  • Web 框架: GoFrame v2
  • WebSocket: gorilla/websocket
  • Docker API: docker/docker/client
5.6.2 关键实现
// 1. 升级 HTTP 为 WebSocket
ws, err := wsUpGrader.Upgrade(r.Response.Writer, r.Request, nil)

// 2. 创建 Docker Exec
execConfig := types.ExecConfig{
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
Tty: true, // 关键:分配伪终端
Cmd: []string{"/bin/bash"},
}
execResp, err := cli.ContainerExecCreate(ctx, containerID, execConfig)

// 3. 劫持连接
resp, err := cli.ContainerExecAttach(ctx, execResp.ID, types.ExecStartCheck{Tty: true})

// 4. 双向转发
// 容器输出 → WebSocket
go func() {
buf := make([]byte, 4096)
for {
n, err := resp.Reader.Read(buf)
if err != nil { return }
ws.WriteMessage(websocket.BinaryMessage, buf[:n])
}
}()

// WebSocket 输入 → 容器
for {
_, msgBytes, err := ws.ReadMessage()
if err != nil { break }

var msg ExecWsMsg
json.Unmarshal(msgBytes, &msg)

switch msg.Type {
case "stdin":
resp.Conn.Write([]byte(msg.Data))
case "resize":
cli.ContainerExecResize(ctx, execID, types.ResizeOptions{
Height: uint(msg.Rows),
Width: uint(msg.Cols),
})
}
}

5.7. 常见问题

5.7.1 连接失败

问题: WebSocket 握手失败 (HTTP 400/401/403)

原因:

  • 未通过 Basic Auth 认证
  • 请求头缺少 Upgrade: websocket

解决:

  • 确保 WebSocket URL 包含认证信息或已通过 Cookie 认证
  • 使用标准 WebSocket 客户端库
5.7.2 容器输出乱码

问题: 终端显示乱码或控制字符

原因:

  • 未使用终端模拟器渲染 ANSI 转义序列
  • 终端大小未正确设置

解决:

  • 使用 xterm.js 等终端模拟器
  • login 后立即发送 resize 消息
5.7.3 连接意外断开

问题: WebSocket 连接在空闲时自动关闭

原因:

  • 中间代理 (Nginx/负载均衡器) 超时
  • 网络不稳定

解决:

  • 定期发送 heartbeat 消息 (建议 30 秒)
  • 配置代理服务器的 WebSocket 超时时间
5.7.4 无法执行交互式命令

问题: vim, top, htop 等命令显示异常

原因:

  • 终端大小未设置或不匹配
  • 未分配伪终端 (Tty)

解决:

  • 确保发送了正确的 resize 消息
  • 后端必须设置 Tty: true (已默认启用)

5.8. 安全建议

  1. 启用 HTTPS/WSS: 生产环境必须使用加密连接
  2. 认证鉴权: 通过 Basic Auth 或 Token 验证用户身份
  3. 容器隔离: 限制用户只能访问自己的容器
  4. 命令审计: 记录所有 stdin 输入到日志
  5. 超时控制: 设置连接最大空闲时间 (如 30 分钟)

5.9. 性能优化

  1. 缓冲区大小: 后端使用 4KB 缓冲区,适合大多数场景
  2. 心跳间隔: 30 秒是推荐值,过短会增加网络开销
  3. 连接复用: 同一容器可以被多个 WebSocket 连接同时访问
  4. 资源清理: 连接断开时自动清理 Docker Exec 会话

5.10. 参考资源

附录: 完整消息类型定义

// TypeScript 类型定义
interface ExecWsMsg {
type: "login" | "stdin" | "resize" | "heartbeat";

// login 字段
container_id?: string;
shell?: string;

// stdin 字段
data?: string;

// resize 字段
cols?: number;
rows?: number;
}

// 使用示例
const loginMsg: ExecWsMsg = {
type: "login",
container_id: "android_slot_0",
shell: "/bin/bash",
};

const stdinMsg: ExecWsMsg = {
type: "stdin",
data: "ls -la\r",
};

const resizeMsg: ExecWsMsg = {
type: "resize",
cols: 120,
rows: 30,
};

const heartbeatMsg: ExecWsMsg = {
type: "heartbeat",
};

五、myt_bridge网卡管理

1. 获取myt_bridge网卡列表

功能说明:获取设备上的myt_bridge网卡列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytBridge

请求参数:无

请求示例

curl "http://192.168.99.108:8000/mytBridge"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 2,
"list": [
{
"name": "myt_bridge",
"cidr": "172.17.0.1/16"
},
{
"name": "myt_bridge_lan",
"cidr": "10.0.0.1/16"
}
]
}
}

失败返回

{
"code": 500,
"message": "获取网卡列表失败",
"data": null
}

2. 创建myt_bridge网卡

功能说明:创建新的myt_bridge网卡

请求方式:POST

请求URL

http://{主机IP}:8000/mytBridge

请求参数

参数名必选类型说明
customNamestring自定义名(最多4字符),会拼接在myt_bridge后面
cidrstringCIDR,例如10.0.0.1/16

请求示例

curl -X POST "http://192.168.99.108:8000/mytBridge" \
-H "Content-Type: application/json" \
-d '{
"customName": "lan",
"cidr": "10.0.0.1/16"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "创建网卡失败: 名称已存在",
"data": null
}

注意事项

  • customName最多4个字符
  • 创建后网卡名为 myt_bridge_customName

3. 更新myt_bridge网卡

功能说明:更新myt_bridge网卡的CIDR配置

请求方式:PUT

请求URL

http://{主机IP}:8000/mytBridge

请求参数

参数名必选类型说明
namestring网卡名(全称或自定义名)
newCidrstring新CIDR,例如10.0.0.1/16

请求示例

curl -X PUT "http://192.168.99.108:8000/mytBridge" \
-H "Content-Type: application/json" \
-d '{
"name": "myt_bridge_lan",
"newCidr": "10.0.0.1/24"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "更新网卡失败: 网卡不存在",
"data": null
}

4. 删除myt_bridge网卡

功能说明:删除指定的myt_bridge网卡

请求方式:DELETE

请求URL

http://{主机IP}:8000/mytBridge

请求参数

参数名必选类型说明
namestring网卡名(全称或自定义名)

请求示例

curl -X DELETE "http://192.168.99.108:8000/mytBridge" \
-H "Content-Type: application/json" \
-d '{
"name": "myt_bridge_lan"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "删除网卡失败: 网卡正在被使用",
"data": null
}

注意事项

  • 正在被云机使用的网卡无法删除
  • 删除前请确保没有云机依赖该网卡

六、macVlan网卡管理

1. 获取网卡详情

功能说明:查询指定 ID 的 macVlan 网卡详细信息

请求方式:GET

请求URL

http://{主机IP}:8000/macvlan

请求参数:无

请求示例

GET "http://192.168.99.108:8000/macvlan"

成功返回

{
"code": 0,
"message": "OK",
"data": {
"macVlan": {
"Name": "myt",
"Id": "24732efd39a53baa9822d49302f701c878e701f2553574fc217e255f1c5289a9",
"Created": "2026-02-04T13:42:39.460109818+08:00",
"Scope": "local",
"Driver": "macvlan",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "192.168.99.0/24",
"Gateway": "192.168.99.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"macvlan_mode": "private",
"parent": "eth0"
},
"Labels": {}
}
}
}

返回参数

参数名类型说明
Attachableboolean是否允许手动附加容器
ConfigFromobject配置来源对象
ConfigFrom.Networkstring来源网络名称
ConfigOnlyboolean是否仅配置(不创建网络)
Containersobject连接到该网络的容器映射,键为容器ID/名称,值为端点信息
Createdstring (time.Time)网络创建时间
Driverstring网络驱动名称(如 bridge, overlay, macvlan 等)
EnableIPv6boolean是否启用IPv6
Idstring网络ID
Ingressboolean是否为Swarm Ingress网络
Internalboolean是否为内部网络(限制外部访问)
IPAMobjectIP地址管理(IPAM)配置
IPAM.DriverstringIPAM驱动名称(如 default)
IPAM.OptionsobjectIPAM驱动选项
IPAM.ConfigarrayIPAM配置列表,每个元素为子网配置
IPAM.Config[].AuxiliaryAddressesobject辅助地址映射,键为地址名,值为IP
IPAM.Config[].Gatewaystring子网网关IP
IPAM.Config[].IPRangestring分配的IP范围(如 172.17.0.0/24)
IPAM.Config[].Subnetstring子网CIDR(如 172.17.0.0/16)
Labelsobject网络标签键值对
Namestring网络名称
Optionsobject网络驱动选项
Peersarray对等节点列表(仅Swarm模式)
Peers[].IPstring对等节点IP地址
Peers[].Namestring对等节点名称
Scopestring网络作用域(local, swarm, global)
Servicesobject服务列表(仅Swarm模式),键为服务名,值为服务信息

失败返回

{
"code": 500,
"message": "获取网卡详情失败",
"data": null
}

2. 创建网卡

功能说明:创建新的macVlan网卡

请求方式:POST

请求URL

http://{主机IP}:8000/macvlan

请求参数

参数名必选类型说明
gwstring网关,例如 192.168.100.1
subnetstring掩码,例如 192.168.100.0/24
privateboolean是否禁止macvlan容器互相访问,默认为 true

请求示例

POST http://192.168.99.108:8000/macvlan
Content-Type: application/json
请求体
{
"gw": "192.168.100.1",
"subnet": "192.168.100.0/24",
"private": true
}

或者

curl http://192.168.99.108:8000/macvlan \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"gw": "",
"subnet": "192.168.100.0/24",
"private": true
}'

成功返回

{
"code": 0,
"message": "OK",
"data": {
"id": "string"
}
}

返回参数

参数名类型说明
idstring创建成功的网卡ID

失败返回

{
"code": 500,
"message": "创建网卡失败",
"data": null
}

3. 更新网卡

功能说明:更新一个已存在的 macVlan 网卡的配置。

请求方式:PUT

请求URL

http://{主机IP}:8000/macvlan

请求参数

参数名必选类型说明
gwstring新的网关,例如 192.168.100.1
subnetstring新的掩码,例如 192.168.100.0/24
privateboolean是否禁止macvlan容器互相访问,默认为 true

请求示例

POST http://192.168.99.108:8000/macvlan
Content-Type: application/json
请求体
{
"gw": "192.168.100.1",
"subnet": "192.168.100.0/24",
"private": true
}

或者

curl http://192.168.99.108:8000/macvlan \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"gw": "192.168.100.1",
"subnet": "192.168.100.0/24",
"private": true
}'

成功返回

{
"code": 0,
"message": "OK",
"data": {
"id": "string"
}
}

返回参数

参数名类型说明
idstring创建成功的网卡ID

失败返回

{
"code": 500,
"message": "创建网卡失败",
"data": null
}

4. 删除网卡

功能说明:更新一个已存在的 macVlan 网卡的配置。

请求方式:DELETE

请求URL

http://{主机IP}:8000/macvlan

请求参数:无

请求示例

curl http://192.168.99.108:8000/macvlan \
--request DELETE

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

七、魔云腾VPC

1. 获取网络分组列表

功能说明:查询所有网络分组列表,支持按别名过滤

请求方式:GET

请求URL

http://{主机IP}:8000/mytVpc/group

请求参数

参数名必选类型说明
aliasstring分组别名,传空查询所有

请求示例

# 查询所有分组
GET "http://{主机IP}:8000/mytVpc/group"
# 按别名过滤
curl "http://192.168.99.108:8000/mytVpc/group?alias=test-group"

成功返回

{
"code": 0,
"message": "OK",
"data": {
"count": 1,
"list": [
{
"id": 11,
"alias": "111saa",
"url": "",
"vpcs": {
"vpcCount": 1,
"list": [
{
"id": 289,
"groupId": 11,
"remarks": "socks_220csx",
"protocol": "socks",
"profile": "{\"configType\":3,\"remarks\":\"socks_220csx\",\"server\":\"nub2ccs1.user.wuyouip.com\",\"serverPort\":\"xxxx\",\"password\":\"xxxx\",\"username\":\"xxxx\"}",
"outConfig": "{\"protocol\":\"socks\",\"sendThrough\":null,\"tag\":\"socks_220csx_11_1769492725191\",\"settings\":{\"servers\":[{\"address\":\"nub2ccs1.user.wuyouip.com\",\"port\":xxxx,\"level\":8,\"users\":[{\"user\":\"xxxxx\",\"pass\":\"xxxxxx\",\"level\":8}]}]},\"streamSettings\":null,\"proxySettings\":null,\"mux\":{\"enabled\":false,\"concurrency\":-1,\"xudpConcurrency\":0,\"xudpProxyUDP443\":\"\"},\"targetStrategy\":\"\"}",
"source": 2,
"tag": "socks_220csx_11_1769492725191"
}
]
}
}
]
}
}

2. 增加网络分组列表

功能说明:创建新的网络分组,支持订阅地址或节点地址模式

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/group

请求参数

参数名必选类型说明
aliasstring网络分组别名
addressesarray批量添加节点列表(source=2 时必填)
sourceint1-订阅地址,2-节点地址,默认
urlstring批量添加节点列表(source=1 时必填)

请求示例

# 订阅地址模式
curl -X POST "http://192.168.99.108:8000/mytVpc/group" \
-H "Content-Type: application/json" \
-d '{
"alias": "test-group",
"source": 1,
"url": "http://example.com/subscribe"
}'
# 节点地址模式
curl -X POST "http://192.168.99.108:8000/mytVpc/group" \
-H "Content-Type: application/json" \
-d '{
"alias": "node-group",
"source": 2,
"addresses": ["192.168.1.100:8080", "192.168.1.101:8080"]
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

# 分组名称未填
{
"code": 51,
"message": "The alias field is required",
"data": null
}
# 填错地址
{
"code": 50,
"message": "Get \"\": unsupported protocol scheme \"\"",
"data": null
}
# 分组已存在
{
"code": 10021,
"message": "Error: 此订阅分组已存在无法新建",
"data": null
}

3. 更新网络分组名

功能说明:修改指定网络分组的别名

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/group/alias

请求参数

参数名必选类型说明
idint网络分组ID
newAliasstring分组新别名

请求示例

curl http://192.168.99.108:8000/mytVpc/group/alias \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"id": 1,
"newAlias": "111"
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "更新分组别名失败: 新别名已存在",
"data": null
}

4. 删除网络分组列表

功能说明:删除指定的网络分组,删除前需确保分组内无 VPC 节点

请求方式:DELETE

请求URL

http://{主机IP}:8000/mytVpc/group

请求参数

参数名必选类型说明
idint网络分组ID

请求示例

curl -X DELETE "http://192.168.99.108:8000/mytVpc/group" \
-H "Content-Type: application/json" \
-d '{
"id": 2
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 10022,
"message": "Error: 此订阅分组不存在",
"data": null
}

5. 指定云机 VPC 节点

功能说明:为指定云机绑定 VPC 节点及 DNS 白名单

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/addRule

请求参数

参数名必选类型说明
namestring云机容器名称
vpcIDintVPC 节点 ID
WhiteListDnsarrayVDNS 白名单列表

请求示例

curl http://192.168.99.108:8000/mytVpc/addRule \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"name": "p738c384c1581ad24c3fcf199684f5f5_13_T00013",
"vpcID": 1,
"WhiteListDns": [
""
]
}

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 51,
"message": "The name field is required",
"data": null
}

{
"code": 10023,
"message": "Error: 此VPC节点不存在",
"data": null
}

6. 已设置云机 VPC 节点

功能说明:查询已绑定 VPC 节点的云机规则列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytVpc/containerRule

请求参数:无

请求示例

curl "http://192.168.99.108:8000/mytVpc/containerRule"

成功返回

{
"code": 0,
"message": "OK",
"data": {
"count": 2,
"list": [
{
"id": 1,
"containerID": "5fd727704a60691f7ed5c13575ac261c0f28eebb9aea8141412818f74fa110d5",
"containerIP": "",
"containerName": "Test_1",
"containerState": "running",
"status": 1,
"groupName": "111saa",
"vpcRemarks": "socks_220csx",
"WhiteListDns": []
},
{
"id": 2,
"containerID": "e2e38a2d7ea53d40e58ba5d54327b807a714139dca0ec69faeb176336686a060",
"containerIP": "172.17.0.7",
"containerName": "p738c384c1581ad24c3fcf199684f5f5_13_T00013",
"containerState": "running",
"status": 1,
"groupName": "test-grup",
"vpcRemarks": "澳洲AX01 50500进阶版 0.3x",
"WhiteListDns": []
}
]
}
}

7. 编辑VPC节点

功能说明:编辑指定VPC节点的配置信息,修改后自动重新生成xray配置并同步到云机

请求方式:PUT

请求URL

http://{主机IP}:8000/mytVpc

请求参数

参数名必选类型说明
vpcIDintegerVPC节点ID
remarksstring新的节点别名
profileobject新的节点配置,修改后自动重新生成xray配置并同步到云机

请求示例

curl -X PUT "http://192.168.99.108:8000/mytVpc" \
-H "Content-Type: application/json" \
-d '{
"vpcID": 1,
"remarks": "新别名",
"profile": {
"configType": 1,
"subscriptionId": "",
"remarks": "",
"server": "",
"serverPort": "",
"password": "",
"method": "",
"flow": "",
"username": "",
"alterId": 1,
"network": "",
"headerType": "",
"host": "",
"path": "",
"seed": "",
"quicSecurity": "",
"quicKey": "",
"mode": "",
"serviceName": "",
"authority": "",
"xhttpMode": "",
"xhttpExtra": "",
"security": "",
"sni": "",
"alpn": "",
"fingerprint": "",
"insecure": true,
"mldsa65Verify": "",
"publicKey": "",
"shortId": "",
"spiderX": "",
"secretKey": "",
"preSharedKey": "",
"localAddress": "",
"reserved": "",
"mtu": 1,
"obfsPassword": "",
"portHopping": "",
"portHoppingInterval": "",
"pinSHA256": "",
"bandwidthDown": "",
"bandwidthUp": "",
"remoteDNS": true,
"caCert": ""
}
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 10023,
"message": "Error: 此VPC节点不存在",
"data": null
}

8. 删除网络分组内节点

功能说明:从指定网络分组中移除一个云机节点。

请求方式:DELETE

请求URL

http://{主机IP}:8000/mytVpc

请求参数

参数名必选类型说明
vpcIDint要删除的 VPC 节点 ID

请求示例

curl -X DELETE "http://192.168.99.108:8000/mytVpc" \
-H "Content-Type: application/json" \
-d '{
"vpcID": 1
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 10023,
"message": "Error: 此VPC节点不存在",
"data": null
}

9. 更新指定网络分组

功能说明:更新指定网络分组的配置信息。

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/group/update

请求参数

参数名必选类型说明
IDint网络分组ID

请求示例

curl -X DELETE "http://192.168.99.108:8000/mytVpc" \
-H "Content-Type: application/json" \
-d '{
"vpcID": 1
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 10022,
"message": "Error: 此订阅分组不存在",
"data": null
}

10. 增加socks5节点

功能说明:向指定网络分组添加 socks5 节点。

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/socks

请求参数

参数名必选类型说明
aliasstring订阅分组别名,如果别名不存在将创建新分组,若存在则加入到此分组中
listarraysocks5 节点列表

list 数组元素结构

字段类型说明
remarksstring节点别名
socksIpstrings5 IP
socksPortints5 端口
socksUserstrings5 用户名
socksPasswordistrings5 密码

请求示例

curl -X POST "http://192.168.99.108:8000/mytVpc/socks" \
-H "Content-Type: application/json" \
-d '{
"alias": "socks-group",
"list": [
{
"remarks": "node1",
"socksIp": "192.168.1.100",
"socksPort": 1080,
"socksUser": "user1",
"socksPassword": "pass123"
}
]
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 51,
"message": "The alias field is required",
"data": null
}

11. 开关DNS白名单

功能说明:启用 / 禁用指定 VPC 规则的 DNS 白名单。

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/whiteListDns

请求参数

参数名必选类型说明
ruleIDint规则 ID
enablebool是否启用,默认 true
whiteListDnsarrayDNS 白名单列表

请求示例

curl http://192.168.99.108:8000/mytVpc/whiteListDns \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"ruleID": 1,
"enable": true,
"whiteListDns": [
""
]
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

12. VPC节点延迟测试

功能说明:测试指定 VPC 节点的网络延迟。

请求方式:GET

请求URL

http://{主机IP}:8000/mytVpc/test

请求参数

参数名必选类型说明
addressstring节点地址,address 格式如 "1.1.1.1:80" 或 "www.google.com:443"

请求示例

curl 'http://192.168.99.108:8000/mytVpc/test?address=50500.b-vm915x.8h2jssajkd.g-songs.ting-wo-shuo-xiexieni.com'

成功返回

{
"code": 0,
"message": "OK",
"data": {
"msg": "dial tcp: address 50500.b-vm915x.8h2jssajkd.g-songs.ting-wo-shuo-xiexieni.com: missing port in address",
"latency": "0ms"
}
}

13. 批量指定云机VPC节点

功能说明:批量指定云机VPC节点

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/addRule/batch

请求参数

参数名必选类型说明
namesarray云机容器名称列表
vpcIDintegervpc节点ID
WhiteListDnsarrayDNS白名单

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"names": ["android_1", "android_2"],
"vpcID": 123,
"WhiteListDns": ["8.8.8.8"]
}' "http://192.168.99.108:8000/mytVpc/addRule/batch"

成功返回

{
"code": 0,
"message": "批量指定成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "批量指定失败",
"data": null
}

14. 清除云机VPC节点

功能说明:清除指定云机的VPC节点

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/delRule

请求参数

参数名必选类型说明
namestring云机容器名称

请求示例

curl -X POST -H "Content-Type: application/json" -d '{"name": "android_1"}' "http://192.168.99.108:8000/mytVpc/delRule"

成功返回

{
"code": 0,
"message": "清除成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "清除失败,容器不存在",
"data": null
}


15. 批量清除云机VPC节点

功能说明:批量清除云机的VPC节点

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/delRule/batch

请求参数

参数名必选类型说明
namestring云机容器名称列表

请求示例

curl -X POST -H "Content-Type: application/json" -d '{"name": ["android_1", "android_2"]}' "http://192.168.99.108:8000/mytVpc/delRule/batch"

成功返回

{
"code": 0,
"message": "批量清除成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "批量清除失败",
"data": null
}

16. 清除容器域名过滤

功能说明:清除指定容器的域名过滤设置

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/domainFilter

请求参数

参数名必选类型说明
containerIDstring容器ID或名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/mytVpc/domainFilter?containerID=abc123"

成功返回

{
"code": 0,
"message": "清除成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "清除失败,容器不存在",
"data": null
}

17. 查询容器域名过滤

功能说明:查询指定容器的域名过滤列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytVpc/domainFilter

请求参数

参数名必选类型说明
containerIDstring容器ID或名称

请求示例

curl -X GET "http://192.168.99.108:8000/mytVpc/domainFilter?containerID=abc123"

成功返回

{
"code": 0,
"message": "查询成功",
"data": {
"domains": ["example.com", "google.com"]
}
}

失败返回

{
"code": 500,
"message": "查询失败,容器不存在",
"data": null
}

18. 设置容器域名过滤

功能说明:设置指定容器的域名过滤列表

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/domainFilter

请求参数

参数名必选类型说明
containerIDstring容器ID或名称
domainsarray域名列表,传空数组则清空

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"containerID": "abc123",
"domains": ["example.com", "google.com"]
}' "http://192.168.99.108:8000/mytVpc/domainFilter"

成功返回

{
"code": 0,
"message": "设置成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置失败",
"data": null
}

19. 清除全局域名过滤

功能说明:清除全局域名过滤设置

请求方式:DELETE

请求URL

http://{主机IP}:8000/mytVpc/domainFilter/global

请求参数:无

请求示例

curl -X DELETE "http://10.10.11.47:8000/mytVpc/domainFilter/global"

成功返回

{
"code": 0,
"message": "清除成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "清除失败",
"data": null
}

20. 查询全局域名过滤

功能说明:查询全局域名过滤列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytVpc/domainFilter/global

请求参数:无

请求示例

curl -X GET "http://192.168.99.108:8000/mytVpc/domainFilter/global"

成功返回

{
"code": 0,
"message": "查询成功",
"data": {
"domains": ["example.com", "*.blocked.com"]
}
}

失败返回

{
"code": 500,
"message": "查询失败",
"data": null
}

21. 设置全局域名过滤

功能说明:设置全局域名过滤列表

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/domainFilter/global

请求参数

参数名必选类型说明
domainsarray域名列表,支持 domain:/full:/keyword:/regexp: 前缀,传空数组则清空

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"domains": ["domain:example.com", "keyword:blocked"]
}' "http://192.168.99.108:8000/mytVpc/domainFilter/global"

成功返回

{
"code": 0,
"message": "设置成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置失败",
"data": null
}

22. 更新网络分组别名

功能说明:更新网络分组别名

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/group/alias

请求参数

参数名必选类型说明
idinteger网络分组ID
newAliasstring分组新别名

请求示例

curl -X POST -H "Content-Type: application/json" -d '{"id":123, "newAlias": "newgroup"}' "http://192.168.99.108:8000/mytVpc/group/alias"

成功返回

{
"code": 0,
"message": "更新成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "更新失败,分组不存在",
"data": null
}

23. 查询容器域名直连

功能说明:查询指定容器的域名直连列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytVpc/domainDirect

请求参数

参数名必选类型说明
containerIDstring容器ID或名称

请求示例

curl "http://192.168.99.108:8000/mytVpc/domainDirect?containerID=abc123"

成功返回

{
"code": 0,
"message": "查询成功",
"data": {
"domains": ["example.com", "google.com"]
}
}

失败返回

{
"code": 500,
"message": "查询失败,容器不存在",
"data": null
}

24. 设置容器域名直连

功能说明:设置指定容器的域名直连列表

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/domainDirect

请求参数

参数名必选类型说明
containerIDstring容器ID或名称
domainsarray域名列表,传空数组则清空

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"containerID": "abc123",
"domains": ["example.com", "google.com"]
}' "http://192.168.99.108:8000/mytVpc/domainDirect"

成功返回

{
"code": 0,
"message": "设置成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置失败",
"data": null
}

25. 清除容器域名直连

功能说明:清除指定容器的域名直连设置

请求方式:DELETE

请求URL

http://{主机IP}:8000/mytVpc/domainDirect

请求参数

参数名必选类型说明
containerIDstring容器ID或名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/mytVpc/domainDirect?containerID=abc123"

成功返回

{
"code": 0,
"message": "清除成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "清除失败,容器不存在",
"data": null
}

26. 查询容器域名中转路由

功能说明:查询指定容器的域名中转路由列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytVpc/domainRoute

请求参数

参数名必选类型说明
containerIDstring容器ID或名称

请求示例

curl "http://192.168.99.108:8000/mytVpc/domainRoute?containerID=abc123"

成功返回

{
"code": 0,
"message": "查询成功",
"data": {
"routes": [
{
"domains": ["domain:example.com", "keyword:test"],
"vpcID": 1
}
]
}
}

返回字段说明

字段类型说明
routesarray域名中转路由列表
domainsarray域名列表,支持 domain:/full:/keyword:/regexp: 前缀
vpcIDinteger目标VPC节点ID

失败返回

{
"code": 500,
"message": "查询失败,容器不存在",
"data": null
}

27. 设置容器域名中转路由

功能说明:设置指定容器的域名中转路由列表,传空数组则清空

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpc/domainRoute

请求参数

参数名必选类型说明
containerIDstring容器ID或名称
routesarray域名中转路由列表,传空数组则清空

routes 数组元素结构

字段类型说明
domainsarray域名列表,支持 domain:/full:/keyword:/regexp: 前缀
vpcIDinteger目标VPC节点ID

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"containerID": "abc123",
"routes": [
{
"domains": ["domain:example.com", "keyword:blocked"],
"vpcID": 1
}
]
}' "http://192.168.99.108:8000/mytVpc/domainRoute"

成功返回

{
"code": 0,
"message": "设置成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "设置失败",
"data": null
}

28. 清除容器域名中转路由

功能说明:清除指定容器的域名中转路由设置

请求方式:DELETE

请求URL

http://{主机IP}:8000/mytVpc/domainRoute

请求参数

参数名必选类型说明
containerIDstring容器ID或名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/mytVpc/domainRoute?containerID=abc123"

成功返回

{
"code": 0,
"message": "清除成功",
"data": {}
}

失败返回

{
"code": 500,
"message": "清除失败,容器不存在",
"data": null
}

八、本地机型数据管理

1. 获取本地机型列表

功能说明:获取设备上的本地机型数据列表

请求方式:GET

请求URL

http://{主机IP}:8000/phoneModel

请求参数:无

请求示例

curl "http://192.168.99.108:8000/phoneModel"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 5,
"list": [
{
"name": "samsung_s23"
},
{
"name": "xiaomi_14"
},
{
"name": "pixel_8"
}
]
}
}

返回字段说明

字段类型说明
namestring机型文件名称

失败返回

{
"code": 500,
"message": "获取本地机型列表失败",
"data": null
}

2. 删除本地机型数据

功能说明:删除指定的本地机型数据

请求方式:DELETE

请求URL

http://{主机IP}:8000/phoneModel

请求参数

参数名必选类型说明
namestring机型文件名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/phoneModel" \
-H "Content-Type: application/json" \
-d '{
"name": "samsung_s23"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "删除本地机型失败: 文件不存在",
"data": null
}

3. 导出本地机型数据

功能说明:导出指定的本地机型数据

请求方式:POST

请求URL

http://{主机IP}:8000/phoneModel/export

请求参数

参数名必选类型说明
namestring机型文件名称

请求示例

curl -X POST "http://192.168.99.108:8000/phoneModel/export" \
-H "Content-Type: application/json" \
-d '{
"name": "samsung_s23"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "导出本地机型失败: 文件不存在",
"data": null
}

4. 导入机型数据

功能说明:通过上传ZIP包导入机型数据

请求方式:POST

请求URL

http://{主机IP}:8000/phoneModel/import

Content-Typemultipart/form-data

请求参数

参数名必选类型说明
filefile导入修改后的机型ZIP包

请求示例

curl -X POST "http://192.168.99.108:8000/phoneModel/import" \
-F "file=@samsung_s23.zip"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "导入机型数据失败: 文件格式错误",
"data": null
}

注意事项

  • 仅支持ZIP格式的机型数据包

九、接口认证

1. 修改认证密码

功能说明:修改API接口认证密码(默认用户名admin)

请求方式:POST

请求URL

http://{主机IP}:8000/auth/password

请求参数

参数名必选类型说明
newPasswordstring新密码
confirmPasswordstring确认新密码

请求示例

curl -X POST "http://192.168.99.108:8000/auth/password" \
-H "Content-Type: application/json" \
-d '{
"newPassword": "newpassword123",
"confirmPassword": "newpassword123"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "修改密码失败: 两次密码不一致",
"data": null
}

注意事项

  • 两次输入的密码必须一致
  • 默认用户名为admin
  • 密码修改后立即生效

2. 关闭接口认证

功能说明:关闭API接口认证功能

请求方式:POST

请求URL

http://{主机IP}:8000/auth/close

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/auth/close"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "关闭认证失败",
"data": null
}

注意事项

  • 关闭认证后,所有接口将无需认证即可访问
  • 出于安全考虑,建议在内网环境下使用

十、服务管理

1. 更新服务

功能说明:在线更新SDK服务到最新版本

请求方式:GET

请求URL

http://{主机IP}:8000/server/upgrade

请求参数:无

请求示例

curl "http://192.168.99.108:8000/server/upgrade"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"msg": "更新成功,服务将自动重启"
}
}

失败返回

{
"code": 500,
"message": "更新失败: 网络连接超时",
"data": null
}

注意事项

  • 更新成功后服务会自动重启
  • 更新过程中请勿断电或断网

2. 通过上传SDK更新服务

功能说明:通过上传SDK压缩包更新服务

请求方式:POST

请求URL

http://{主机IP}:8000/server/upgrade/upload

Content-Typemultipart/form-data

请求参数

参数名必选类型说明
filefileSDK压缩包文件,zip格式

请求示例

curl -X POST "http://192.168.99.108:8000/server/upgrade/upload" \
-F "file=@myt-sdk-v1.2.0.zip"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "更新失败: 文件格式错误",
"data": null
}

注意事项

  • 仅支持zip格式的SDK压缩包
  • 更新成功后服务会自动重启

3. 清空设备磁盘数据

功能说明:清空设备磁盘上的所有数据(高危操作!)

请求方式:POST

请求URL

http://{主机IP}:8000/server/device/reset

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/server/device/reset"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "清空数据失败",
"data": null
}

注意事项

  • ⚠️ 高危操作!此操作将清空设备上的所有数据,不可恢复!
  • 执行前请确保已备份所有重要数据
  • 操作完成后设备将恢复出厂状态

4. 重启设备

功能说明:重启设备

请求方式:POST

请求URL

http://{主机IP}:8000/server/device/reboot

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/server/device/reboot"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"message": "设备将在5秒后重启"
}
}

失败返回

{
"code": 500,
"message": "重启设备失败",
"data": null
}

注意事项

  • 重启过程中所有云机将停止运行
  • 重启完成后需要手动启动云机

5. 开启和屏蔽dockerApi 2375端口

功能说明:控制主机上 Docker Remote API(端口 2375)的开启或屏蔽状态

请求方式:POST

请求URL

http://{主机IP}:8000/server/dockerApi

请求参数

参数名必选类型说明
enablebooleantrue 表示开启,false 表示屏蔽

请求示例

curl -X POST "http://192.168.99.108:8000/server/dockerApi" \
-H "Content-Type: application/json" \
-d '{"enable": true}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "操作失败",
"data": null
}

6. 获取主机网络信息

功能说明:获取设备当前的网络配置信息,包括网关、子网和网卡接口

请求方式:GET

请求URL

http://{主机IP}:8000/server/network

请求参数:无

请求示例

curl http://192.168.99.108:8000/server/network

成功返回

{
"code": 0,
"message": "ok",
"data": {
"info": {
"gateway": "192.168.99.1",
"networkCIDR": "192.168.99.0/24",
"interface": "eth0"
}
}
}

失败返回

{
"code": 500,
"message": "获取网络信息失败",
"data": null
}

7. 修复SSH服务

功能说明:修复SSH服务

请求方式:POST

请求URL

http://{主机IP}:8000/server/ssh/fix

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/server/ssh/fix"

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "修复SSH服务失败",
"data": null
}

十一、大模型管理

1. 导入大模型 ZIP 包

功能说明:导入大模型 ZIP 包到设备中

请求方式:POST

请求URL

http://{主机IP}:8000/lm/import

请求参数

参数名必选类型说明
filefile大模型 ZIP 包文件(multipart/form-data 格式)

请求示例

curl -X POST -F "file=@./llm_model.zip" "http://192.168.99.108:8000/lm/import"

成功返回

{
"code": 0,
"message": "导入大模型ZIP包成功",
"data": null
}

失败返回

{
"code": 500,
"message": "导入大模型ZIP包失败,文件格式错误或损坏",
"data": null
}

2. 解压大模型ZIP包

功能说明:解压 /mmc/mytLLM 目录下已上传的大模型 ZIP 包,解压完成后返回模型目录名和文件数

请求方式:POST

请求URL

http://{主机IP}:8000/lm/extract

请求参数

参数名必选类型说明
filenamestring/mmc/mytLLM 下待解压的 ZIP 文件名

请求示例

curl -X POST "http://192.168.99.108:8000/lm/extract" \
-H "Content-Type: application/json" \
-d '{
"filename": "chatglm3.zip"
}'

成功返回

{
"code": 0,
"message": "解压成功",
"data": {
"modelName": "chatglm3",
"fileCount": 12
}
}

返回字段说明

字段类型说明
modelNamestring解压后的模型目录名
fileCountinteger解压出的文件数

失败返回

{
"code": 500,
"message": "解压失败: 文件不存在或格式错误",
"data": null
}

3. 获取系统信息

功能说明:获取设备及大模型相关系统信息

请求方式:GET

请求URL

http://{主机IP}:8000/lm/info

请求参数:无

请求示例

curl "http://192.168.99.108:8000/lm/info"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"api_version": "v1.0.0",
"nsmi_version": "1.2.3",
"pcie_driver_version": "4.5.6",
"firmware_version": "v2.1.0",
"devices": [
{
"device_id": 1,
"mode": "PCIE",
"global_id": 1001,
"internal_id": 101,
"fan_speed_ratio": 50,
"temp": 42,
"power": 35,
"voltage": 12,
"chips": [
{
"chip_id": 10001,
"chip_name": "RK3588",
"chip_ver": "v1.1",
"cpu_id": "CPU001",
"health": 0,
"temp": 40,
"memory_info": {
"total_size": 8589934592,
"free_size": 4294967296,
"util_rate": 50,
"hugepage_size": 2097152,
"hugepage_total_cnt": 1024,
"hugepage_free_cnt": 512
}
}
]
}
]
}
}

返回字段说明

参数名类型说明
api_versionstringAPI 版本
firmware_versionstring固件版本
devicesarray设备列表
device_idinteger设备全局 ID
chipsarray芯片列表
memory_infoobject内存信息
total_sizeinteger总内存大小(Bytes)
util_rateinteger内存使用率(%)

失败返回

{
"code": 500,
"message": "获取系统信息失败",
"data": null
}

4. 删除本地大模型

功能说明:删除设备上指定名称的本地大模型

请求方式:DELETE

请求URL

http://{主机IP}:8000/lm/local

请求参数

参数名必选类型说明
namestring本地大模型名称

请求示例

curl -X DELETE "http://192.168.99.108:8000/lm/local?name=chatglm3"

成功返回

{
"code": 0,
"message": "删除本地大模型成功",
"data": null
}

失败返回

{
"code": 500,
"message": "删除本地大模型失败,模型不存在",
"data": null
}

5. 获取本地大模型列表

功能说明:获取设备上所有本地大模型的列表信息

请求方式:GET

请求URL

http://{主机IP}:8000/lm/local

请求参数:无

请求示例

curl "http://192.168.99.108:8000/lm/local"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 2,
"list": [
{
"name": "chatglm3",
"size": "10GB",
"files": [
{
"filePath": "/models/chatglm3/main.rknn",
"size": "8GB"
},
{
"filePath": "/models/chatglm3/vocab.json",
"size": "200MB"
}
]
},
{
"name": "llama2",
"size": "15GB",
"files": [
{
"filePath": "/models/llama2/model.rknn",
"size": "12GB"
},
{
"filePath": "/models/llama2/tokenizer.gguf",
"size": "300MB"
}
]
}
]
}
}

返回字段说明

参数名类型说明
countinteger本地大模型总数
namestringstring
sizearray大模型总大小
filesarray大模型包含文件列表
filePathstring文件路径

失败返回

{
"code": 500,
"message": "获取本地大模型列表失败",
"data": null
}

6. 获取模型运行状态

功能说明:获取当前设备上大模型的运行状态信息

请求方式:GET

请求URL

http://{主机IP}:8000/lm/models

请求参数:无

请求示例

curl "http://192.168.99.108:8000/lm/models"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"object": "model_list",
"data": [
{
"id": "model_001",
"object": "model",
"created": 1735689600,
"owned_by": "local",
"meta": {
"ctx_size": 2048,
"predict": 1024,
"temp": 0.7
}
}
]
}
}

返回字段说明

参数名类型说明
idstring模型 ID
createdinteger创建时间戳
metaobject模型元数据
ctx_sizeinteger上下文窗口大小

失败返回

{
"code": 500,
"message": "获取模型运行状态失败",
"data": null
}

7. 重置设备

功能说明:对指定设备进行硬件或软件重置

请求方式:POST

请求URL

http://{主机IP}:8000/lm/reset

请求参数

参数名必选类型说明
typestring重置类型(hw - 硬件,sw - 软件)
device_idinteger设备 ID

请求示例

curl -X POST -H "Content-Type: application/json" -d '{"type":"sw","device_id":1}' "http://192.168.99.108:8000/lm/reset"

成功返回

{
"code": 0,
"message": "设备重置成功",
"data": null
}

失败返回

{
"code": 500,
"message": "设备重置失败,设备ID不存在",
"data": null
}

8. 启动 LLM 服务

功能说明:启动指定配置的 LLM 服务

请求方式:POST

请求URL

http://{主机IP}:8000/lm/server/start

请求参数

参数名必选类型说明
hoststring监听地址,默认值:0.0.0.0
portinteger监听端口,默认值:8081
timeoutinteger超时时间(秒),默认值:30
modelsobject模型配置列表(key 为模型别名)
aliasstring模型别名(与 key 一致)
modelstring主模型文件路径(RKNN)
weightstring主模型权重路径
ctx-sizeinteger上下文窗口大小,默认值:0
tempnumber温度参数,默认值:0.8

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"host": "0.0.0.0",
"port": 8081,
"timeout": 30,
"models": {
"chatglm3": {
"alias": "chatglm3",
"model": "/models/chatglm3/main.rknn",
"weight": "/models/chatglm3/weight.bin",
"ctx-size": 2048,
"temp": 0.7
}
}
}' "http://192.168.99.108:8000/lm/server/start"

成功返回

{
"code": 0,
"message": "LLM服务启动成功",
"data": null
}

失败返回

{
"code": 500,
"message": "LLM服务启动失败,模型文件不存在",
"data": null
}

9. 停止 LLM 服务

功能说明:停止当前运行的 LLM 服务

请求方式:POST

请求URL

http://{主机IP}:8000/lm/server/stop

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/lm/server/stop"

成功返回

{
"code": 0,
"message": "LLM服务停止成功",
"data": null
}

失败返回

{
"code": 500,
"message": "LLM服务停止失败,服务未运行",
"data": null
}

10. 设置工作模式

功能说明:设置指定设备和芯片的工作模式

请求方式:POST

请求URL

http://{主机IP}:8000/lm/workMode

请求参数

参数名必选类型说明
device_idinteger设备 ID
chip_idinteger芯片 ID
work_modeinteger工作模式,默认值:2

请求示例

curl -X POST -H "Content-Type: application/json" -d '{"device_id":1,"chip_id":10001,"work_mode":2}' "http://192.168.99.108:8000/lm/workMode"

成功返回

{
"code": 0,
"message": "工作模式设置成功",
"data": null
}

失败返回

{
"code": 500,
"message": "工作模式设置失败,设备或芯片ID不存在",
"data": null
}

11. 模型推理对话补全

功能说明:模型推理对话补全

请求方式:POST

请求URL

http://{主机IP}:8000/v1/chat/completions

请求参数

参数名必选类型说明
modelstring模型别名
messagesarray对话历史,每个元素包含 role 和 content
streamboolean是否流式返回,默认 true
max_tokensinteger最大生成 Token 数,默认 2048
temperaturenumber随机性 (0-1),默认 0.7
top_pnumber核采样概率,默认 0.9

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"model": "llama3",
"messages": [
{"role": "user", "content": "Hello, who are you?"}
],
"stream": true,
"max_tokens": 2048,
"temperature": 0.7,
"top_p": 0.9
}' "http://192.168.99.108:8000/v1/chat/completions"

成功返回

{
"code": 0,
"message": "操作成功",
"data": {
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1677652288,
"model": "llama3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "I am an AI assistant."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30
}
}
}

失败返回

{
"code": 500,
"message": "模型不存在或服务异常",
"data": null
}

12. 模型文本向量化

功能说明:模型文本向量化

请求方式:POST

请求URL

http://{主机IP}:8000/v1/embeddings

请求参数

参数名必选类型说明
modelstring模型别名
inputstring/array输入文本,可以是字符串或字符串数组
dimensionsinteger返回的向量维度(仅V3模型支持)
encoding_formatstring返回向量的格式,float 或 base64,默认 float

请求示例

curl -X POST -H "Content-Type: application/json" -d '{
"model": "text-embedding-3-small",
"input": "The quick brown fox jumps over the lazy dog",
"dimensions": 256,
"encoding_format": "float"
}' "http://192.168.99.108:8000/v1/embeddings"

成功返回

{
"code": 0,
"message": "操作成功",
"data": {
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [0.1, 0.2, 0.3, 0.4]
}
],
"model": "text-embedding-3-small",
"usage": {
"prompt_tokens": 10,
"total_tokens": 10
}
}
}

失败返回

{
"code": 500,
"message": "向量化失败,模型不支持或输入格式错误",
"data": null
}

十二、云机操作V2镜像

1. 创建云机V2

功能说明:创建一个新的安卓云机实例。

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2

请求参数

参数名必选类型说明
namestring云机名称
indexNuminteger实例序号,P1范围1-24,Q1范围1-12,传0将自动分配一个空闲实例序号
imageUrlstring镜像完整地址
sandboxSizestring沙盒大小,例如 "16GB","32GB"
dnsstring云机DNS,例如 "223.5.5.5"
offsetstring云机的开机时间
doboxFpsstring云机FPS
doboxWidthstring云机分辨率的宽
doboxHeightstring云机分辨率的高
doboxDpistring云机DPI
enforceboolean安全模式,默认开启
macVlanIpstring独立IP设置
startboolean创建完成是否开机,默认为 true
vpcIDinteger添加的魔云腾VPC节点ID
portMappingsarray增加自定义端口映射,格式见下方示例
mytBridgeNamestringmyt_bridge网卡名,可以接口查询或在设备终端使用ifconfig查询

请求示例

POST http://192.168.99.108:8000/androidv2
Content-Type: application/json
请求体
{
"name": "test-cloud-phone-v2",
"indexNum": 0,
"imageUrl": "registry.example.com/android:12.0-base",
"sandboxSize": "32GB",
"dns": "8.8.8.8",
"offset": "08:00",
"doboxFps": "60",
"doboxWidth": "1080",
"doboxHeight": "1920",
"doboxDpi": "480",
"enforce": true,
"macVlanIp": "192.168.100.100",
"start": true,
"vpcID": 0,
"portMappings": [
{
"containerPort": 5555,
"hostPort": 55550,
"hostIP": "0.0.0.0",
"protocol": "tcp"
}
],
"mytBridgeName": "myt_bridge_default"
}

成功返回

{
"code": 0,
"message": "OK",
"data": {
"id": "string"
}
}

失败返回

{
"code": 50,
"message": "失败原因",
"data": {
"id": ""
}
}

2. 重置云机V2

功能说明:重置指定名称的安卓云机实例,恢复到初始状态。

请求方式:PUT

请求URL

http://{主机IP}:8000/androidV2

请求参数

参数名必选类型说明
namestring云机名称

请求示例

curl http://192.168.99.108:8000/androidV2 \
--request PUT \
--header 'Content-Type: application/json' \
--data '{
"name": "test-cloud-phone-v2"
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "重置云机失败",
"data": null
}

3. 批量切换容器镜像

功能说明:将多个指定名称的安卓云机批量切换到一个新的镜像。

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/change-image

请求参数

参数名必选类型说明
containerNamesarray云机名称列表
imagestring新的镜像地址

请求示例

POST http://192.168.99.108:8000/androidV2/change-image
Content-Type: application/json
请求体
{
"containerNames": [
"test-cloud-phone-v2",
"test-cloud-phone-v2-2"
],
"image": "registry.example.com/android:12.0-base"
}
或者
curl http://192.168.99.108:8000/androidV2/change-image \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"containerNames": [
"test-cloud-phone-v2",
"test-cloud-phone-v2-2"
],
"image": "registry.example.com/android:12.0-base"
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "批量切换容器镜像失败",
"data": null
}

4. 复制云机

功能说明:复制指定名称的安卓云机实例。

请求方式:GET

请求URL

http://{主机IP}:8000/androidV2/copy

请求参数

参数名必选类型说明
namestring云机名称
indexNuminteger坑位数
countinteger复制数量,默认为1

请求示例

GET "http://192.168.99.108:8000/androidV2/copy?name=test&indexNum=1&count=1"

curl 'http://192.168.99.108:8000/androidV2/copy?name=test&indexNum=1&count=1'

成功返回

data: {"current":1,"total":1,"name":"test_copy_1","status":"copying","message":"正在复制 data 目录"}

data: {"current":1,"total":1,"name":"test_copy_1","status":"copying","message":"正在创建容器"}

data: {"current":1,"total":1,"name":"test_copy_1","status":"success","message":"27cccd9e0ef05c089c92f4831d191bee9cc20c00db8695f920968d6e2d927181"}

data: {"current":1,"total":1,"name":"","status":"done","message":"","success":["test_copy_1"]}

失败返回

{
"code": 500,
"message": "失败原因",
"data": null
}

5. 切换安卓镜像

功能说明:切换指定名称的安卓云机实例的镜像。

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/switchImage

请求参数

参数名必选类型说明
imageUrlstring镜像完整地址称
namestring云机名称像地址
adbPortinteger自定义adb端口,默认5555,设置端口0的时候不开启adb,请不要使用9082、9083、10000、10001、10006、10007、10008等端口
dnsstring云机DNS,例如223.5.5.5
doboxDpistring云机DPI
doboxFpsstring云机的帧率(FPS)
doboxWidthstring云机分辨率的宽度
doboxHeightstring云机分辨率的高度
enforcestring是否启用安全模式,默认开启
macVlanIpstring独立 IP 设置,用于为云机分配一个固定的 MACVLAN IP 地址。
mytBridgeNamestringmyt_bridge 网卡名称,可通过接口查询或在设备终端使用 ifconfig 查询。
offsetstring云机的开机时间度
portMappingsstring增加自定义端口映射
startboolean创建完成开机,默认不开机
vpcIDinteger添加的魔云腾VPC节点ID

自定义端口映射

参数名必选类型说明
containerPortinteger容器内端口,如 80
hostIPstring主机IP,如 0.0.0.0 或 不填
hostPortinteger主机端口,如 8080
protocolstring协议,如 tcp、udp, 默认tcp

请求示例

POST http://192.168.99.183:8000/androidV2/switchImage
Content-Type: application/json
请求体
{
"name": "1773039649840_3_T0003",
"imageUrl": "registry.cn-guangzhou.aliyuncs.com/mytos/dobox:P10_base_202509221352"
}

# 或使用curl
curl http://192.168.99.183:8000/androidV2/switchImage \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"name": "1773039649840_3_T0003",
"imageUrl": "registry.cn-guangzhou.aliyuncs.com/mytos/dobox:P10_base_202509221352",
"dns": "",
"offset": "",
"doboxFps": "",
"doboxWidth": "",
"doboxHeight": "",
"doboxDpi": "",
"enforce": true,
"macVlanIp": "",
"start": true,
"vpcID": 0,
"adbPort": 5555,
"portMappings": [
{
"containerPort": 0,
"hostPort": 0,
"hostIP": "",
"protocol": "tcp"
}
]
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 10006,
"message": "Error: 容器不存在无法操作,请确认容器名称是否正确",
"data": null
}

6. 导出安卓云机V2

功能说明:导出指定名称的安卓云机V2实例

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/export

请求参数

参数名必选类型说明
namestring云机名称

请求示例

curl -X POST "http://192.168.99.108:8000/androidV2/export" \
-H "Content-Type: application/json" \
-d '{
"name": "test-cloud-phone-v2"
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "导出云机V2失败",
"data": null
}

7. 导出安卓云机V2到共享存储

功能说明:导出指定名称的安卓云机V2实例到共享存储

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/exportToOss

请求参数

参数名必选类型说明
namestring云机名称
ossUrlstring共享存储地址
bucketstring存储桶名称
filePathstring文件存储路径
accessKeystring访问密钥

请求示例

curl -X POST "http://192.168.99.108:8000/androidV2/exportToOss" \
-H "Content-Type: application/json" \
-d '{
"name": "test-cloud-phone-v2",
"ossUrl": "https://oss.example.com",
"bucket": "my-bucket",
"filePath": "backups/v2-android-01.tar.gz"
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "导出云机V2到共享存储失败",
"data": null
}

8. 导入安卓云机V2

功能说明:导入安卓云机V2备份包

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/import

Content-Typemultipart/form-data

请求参数

参数名必选类型说明
filefile导入V2导出的云机备份
namestring导入后云机名称
indexNuminteger实例序号,0=自动分配
startboolean导入完成开机,默认开机

请求示例

curl -X POST "http://192.168.99.108:8000/androidV2/import" \
-F "file=@v2-backup.tar.gz" \
-F "name=imported-v2-phone" \
-F "indexNum=0" \
-F "start=true"

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "导入云机V2失败",
"data": null
}

9. 通过URL导入安卓云机V2

功能说明:通过备份包直链地址导入安卓云机V2

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/importByUrl

请求参数

参数名必选类型说明
urlstring备份包直链地址,仅支持http/https
namestring导入后云机名称
indexNuminteger实例序号,0=自动分配
startboolean导入完成开机,默认开机

请求示例

curl -X POST "http://192.168.99.108:8000/androidV2/importByUrl" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/backups/v2-android-01.tar.gz",
"name": "imported-v2-phone",
"indexNum": 0,
"start": true
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "通过URL导入云机V2失败",
"data": null
}

10. 移动云机V2到指定实例位

功能说明:将指定云机V2移动到目标实例位

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/move

请求参数

参数名必选类型说明
namestring云机名称
indexNuminteger目标实例序号,P1范围1-24,Q1范围1-12
startboolean移动完成后开机,默认不开机

请求示例

curl -X POST "http://192.168.99.108:8000/androidV2/move" \
-H "Content-Type: application/json" \
-d '{
"name": "test-cloud-phone-v2",
"indexNum": 5,
"start": true
}'

成功返回

{
"code": 0,
"message": "OK",
"data": null
}

失败返回

{
"code": 500,
"message": "移动云机V2失败: 目标实例位已被占用",
"data": null
}

11. 批量安装APK到云机V2

功能说明:向多个 V2 镜像云机批量安装 APK,支持多个 APK 下载地址,异步执行并返回任务ID

请求方式:POST

请求URL

http://{主机IP}:8000/androidV2/batchInstallApk

请求参数

参数名必选类型说明
apkUrlsarrayAPK下载地址数组
containerNamesarray云机名数组

请求示例

curl -X POST "http://192.168.99.108:8000/androidV2/batchInstallApk" \
-H "Content-Type: application/json" \
-d '{
"apkUrls": [
"https://example.com/app1.apk",
"https://example.com/app2.apk"
],
"containerNames": [
"android-01",
"android-02",
"android-03"
]
}'

成功返回

{
"code": 0,
"message": "OK",
"data": {
"taskId": "mdezt502491dgy413sp0hpf200goqkoa",
"message": "任务已提交,请使用 taskId 查询进度",
"total": 6
}
}

返回字段说明

字段类型说明
taskIdstring任务ID,用于查询安装进度
messagestring提示信息
totalint总安装次数 = APK数量 × 云机数量(apkUrls×containerNames)

失败返回

{
"code": 51,
"message": "The apkUrls field is required",
"data": null
}

注意事项

  • 任务为异步执行,请使用 /android/task-status 接口传入返回的 taskId 查询进度
  • total 为安装总次数,等于 APK 数量乘以云机数量


十三、用户

1. 登录获取魔云腾Token

功能说明:登录魔云腾平台获取Token,用于同步授权

请求方式:POST

请求URL

http://{主机IP}:8000/user/loginIn

请求参数

参数名必选类型说明
namestring用户名
passwordstring密码

请求示例

curl -X POST "http://192.168.99.108:8000/user/loginIn" \
-H "Content-Type: application/json" \
-d '{
"name": "username",
"password": "password123"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"mytToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}

返回字段说明

字段类型说明
mytTokenstring魔云腾访问Token

失败返回

{
"code": 500,
"message": "登录失败: 用户名或密码错误",
"data": null
}

2. 同步授权

功能说明:同步魔云腾平台授权信息到本地

请求方式:GET

请求URL

http://{主机IP}:8000/user/sync

请求参数

参数名必选类型说明
mytTokenstring魔云腾Token

请求示例

curl "http://192.168.99.108:8000/user/sync?mytToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "同步授权失败: Token无效",
"data": null
}

十四、iSCSI磁盘管理

1. 查询iSCSI存储状态

功能说明:查询当前设备的iSCSI存储状态信息

请求方式:GET

请求URL

http://{主机IP}:8000/mytIscsi/status

请求参数:无

请求示例

curl "http://192.168.99.108:8000/mytIscsi/status"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"mode": "local",
"connected": false,
"portal": "",
"iqn": ""
}
}

失败返回

{
"code": 500,
"message": "查询iSCSI存储状态失败",
"data": null
}

2. 查询已挂载iSCSI磁盘列表

功能说明:查询当前设备已挂载的iSCSI磁盘列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytIscsi/list

请求参数:无

请求示例

curl "http://192.168.99.108:8000/mytIscsi/list"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"disks": []
}
}

失败返回

{
"code": 500,
"message": "查询iSCSI磁盘列表失败",
"data": null
}

3. 获取设备可用网卡列表

功能说明:获取设备上可用于iSCSI连接的网卡列表

请求方式:GET

请求URL

http://{主机IP}:8000/mytIscsi/listNic

请求参数:无

请求示例

curl "http://192.168.99.108:8000/mytIscsi/listNic"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"nics": [
{
"name": "eth0",
"ip": "192.168.99.108"
}
]
}
}

失败返回

{
"code": 500,
"message": "获取网卡列表失败",
"data": null
}

4. 发现iSCSI Target

功能说明:发现指定地址的iSCSI Target

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/discover

请求参数

参数名必选类型说明
portalstringTarget地址,例如192.168.1.100:3260

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/discover" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:3260"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "发现iSCSI Target失败",
"data": null
}

5. 挂载iSCSI磁盘

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/login

请求参数

参数名必选类型说明
portalstringTarget地址,例如192.168.1.100:3260
iqnstringTarget IQN标识
localIPstring指定本地网卡IP,为空则自动选择

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/login" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:3260",
"iqn": "iqn.2001-04.com.example:storage.target01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "挂载iSCSI磁盘失败",
"data": null
}

6. 卸载iSCSI磁盘

功能说明:卸载指定iSCSI磁盘

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/logout

请求参数

参数名必选类型说明
portalstringTarget地址
iqnstringTarget IQN标识

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/logout" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:3260",
"iqn": "iqn.2001-04.com.example:storage.target01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "卸载iSCSI磁盘失败",
"data": null
}

7. 挂载iSCSI磁盘到系统并切换存储模式

功能说明:挂载iSCSI磁盘到系统并切换存储模式

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/mount

请求参数

参数名必选类型说明
portalstringTarget地址
iqnstringTarget IQN标识
localIPstring指定本地网卡IP
autoInitboolean是否自动分区格式化(首次挂载时)

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/mount" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:3260",
"iqn": "iqn.2001-04.com.example:storage.target01",
"autoInit": true
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "挂载iSCSI磁盘失败",
"data": null
}

8. 卸载iSCSI磁盘并恢复本地存储模式

功能说明:卸载iSCSI磁盘并恢复本地存储模式

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/umount

请求参数

参数名必选类型说明
portalstringTarget地址
iqnstringTarget IQN标识
forceboolean强制卸载(即使有进程占用)

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/umount" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:3260",
"iqn": "iqn.2001-04.com.example:storage.target01",
"force": false
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "卸载iSCSI磁盘失败",
"data": null
}

9. 对iSCSI磁盘分区

功能说明:对iSCSI磁盘进行分区操作

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/partition

请求参数

参数名必选类型说明
devicestring块设备路径,例如/dev/sdX
labelstring分区表类型:gpt或msdos

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/partition" \
-H "Content-Type: application/json" \
-d '{
"device": "/dev/sdb",
"label": "gpt"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "分区失败",
"data": null
}

10. 格式化iSCSI分区

功能说明:格式化iSCSI分区

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/format

请求参数

参数名必选类型说明
partitionstring分区设备路径,例如/dev/sdX1
fsTypestring文件系统类型,例如ext4、xfs

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/format" \
-H "Content-Type: application/json" \
-d '{
"partition": "/dev/sdb1",
"fsType": "ext4"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "格式化失败",
"data": null
}

11. 在Target上创建磁盘映像

功能说明:在iSCSI Target上创建磁盘映像

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/createDiskImage

请求参数

参数名必选类型说明
portalstringTarget管理地址,例如192.168.1.100:9000
namestring映像名称,例如disk1
sizeinteger映像大小,单位GB
typestring映像类型:fixed=固定大小,thin=动态扩展

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/createDiskImage" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:9000",
"name": "disk1",
"size": 100,
"type": "thin"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "创建磁盘映像失败",
"data": null
}

12. 删除Target上的磁盘映像

功能说明:删除iSCSI Target上的磁盘映像

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/deleteDiskImage

请求参数

参数名必选类型说明
portalstringTarget管理地址,例如192.168.1.100:9000
namestring映像名称
forceboolean强制删除(先强制清理本设备的iSCSI session)

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/deleteDiskImage" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:9000",
"name": "disk1",
"force": false
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "删除磁盘映像失败",
"data": null
}

13. 清理iSCSI残留状态

功能说明:清理iSCSI残留状态(残留session、挂载、node记录)

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/cleanup

请求参数

参数名必选类型说明
portalstringTarget地址
iqnstringTarget IQN标识
forceboolean强制清理(即使有进程占用挂载点)

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/cleanup" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:3260",
"iqn": "iqn.2001-04.com.example:storage.target01",
"force": false
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "清理iSCSI残留状态失败",
"data": null
}

14. 扩容当前iSCSI磁盘分区和文件系统

功能说明:扩容当前iSCSI磁盘分区和文件系统

请求方式:POST

请求URL

http://{主机IP}:8000/mytIscsi/resize

请求参数

参数名必选类型说明
portalstringTarget地址,可选;为空则扩容当前挂载设备
iqnstringTarget IQN标识,可选;为空则扩容当前挂载设备

请求示例

curl -X POST "http://192.168.99.108:8000/mytIscsi/resize" \
-H "Content-Type: application/json" \
-d '{
"portal": "192.168.1.100:3260",
"iqn": "iqn.2001-04.com.example:storage.target01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "扩容iSCSI磁盘失败",
"data": null
}

十五、RPA自动化

1. 连接RPA服务

功能说明:连接指定云机的RPA服务

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/connect

请求参数

参数名必选类型说明
namestring云机容器名称

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/connect" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "连接RPA服务失败",
"data": null
}

2. 断开RPA连接

功能说明:断开指定云机的RPA连接

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/disconnect

请求参数

参数名必选类型说明
namestring云机容器名称

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/disconnect" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "断开RPA连接失败",
"data": null
}

3. 检查RPA连接

功能说明:检查指定云机的RPA连接状态

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/check

请求参数

参数名必选类型说明
namestring云机容器名称

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/check" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "RPA连接检查失败",
"data": null
}

4. 单击

功能说明:在指定坐标位置执行单击操作

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/click

请求参数

参数名必选类型说明
namestring云机容器名称
xintegerX坐标
yintegerY坐标

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/click" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"x": 540,
"y": 960
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "单击操作失败",
"data": null
}

5. 双击

功能说明:在指定坐标位置执行双击操作

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/double_click

请求参数

参数名必选类型说明
namestring云机容器名称
xintegerX坐标
yintegerY坐标

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/double_click" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"x": 540,
"y": 960
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "双击操作失败",
"data": null
}

6. 长按

功能说明:在指定坐标位置执行长按操作

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/long_press

请求参数

参数名必选类型说明
namestring云机容器名称
xintegerX坐标
yintegerY坐标
durationinteger长按时长(ms)

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/long_press" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"x": 540,
"y": 960,
"duration": 1000
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "长按操作失败",
"data": null
}

7. 滑动

功能说明:从起点坐标滑动到终点坐标

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/swipe

请求参数

参数名必选类型说明
namestring云机容器名称
x1integer起点X坐标
y1integer起点Y坐标
x2integer终点X坐标
y2integer终点Y坐标
durationinteger滑动时长(ms)

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/swipe" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"x1": 540,
"y1": 1500,
"x2": 540,
"y2": 500,
"duration": 300
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "滑动操作失败",
"data": null
}

8. 多点触控

功能说明:执行多点触控操作

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/touch

请求参数

参数名必选类型说明
namestring云机容器名称
actionstring动作: down/move/up
xintegerX坐标
yintegerY坐标
touchIdinteger触控点ID

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/touch" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"action": "down",
"touchId": 0,
"x": 540,
"y": 960
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "触控操作失败",
"data": null
}

9. 按键

功能说明:执行按键操作

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/key

请求参数

参数名必选类型说明
namestring云机容器名称
codeinteger按键码: HOME=3, BACK=4, RECENT=187

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/key" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"code": 3
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "按键操作失败",
"data": null
}

10. 输入文本

功能说明:向指定云机输入文本

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/type

请求参数

参数名必选类型说明
namestring云机容器名称
textstring要输入的文本

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/type" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"text": "Hello World"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "输入文本失败",
"data": null
}

11. 截屏

功能说明:截取指定云机的屏幕截图

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/screenshot

请求参数

参数名必选类型说明
namestring云机容器名称
qualityinteger质量1-100
forVlmbooleanVLM友好模式(缩放到540px)
xinteger裁剪区域左上角X坐标,不传则从最左侧开始
yinteger裁剪区域左上角Y坐标,不传则从最上方开始
winteger裁剪区域宽度,不传则截取到右边界
hinteger裁剪区域高度,不传则截取到下边界

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/screenshot" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"quality": 80
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"image": "base64编码的图片数据"
}
}

失败返回

{
"code": 500,
"message": "截屏失败",
"data": null
}

12. 获取UI节点树

功能说明:获取指定云机的UI节点树

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/dump_ui

请求参数

参数名必选类型说明
namestring云机容器名称

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/dump_ui" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"ui": "UI节点树XML数据"
}
}

失败返回

{
"code": 500,
"message": "获取UI节点树失败",
"data": null
}

13. 屏幕是否亮屏

功能说明:检查指定云机屏幕是否亮屏

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/is_screen_on

请求参数

参数名必选类型说明
namestring云机容器名称

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/is_screen_on" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"screenOn": true
}
}

失败返回

{
"code": 500,
"message": "查询屏幕状态失败",
"data": null
}

14. 屏幕旋转角度

功能说明:获取指定云机的屏幕旋转角度

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/rotation

请求参数

参数名必选类型说明
namestring云机容器名称

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/rotation" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"rotation": 0
}
}

失败返回

{
"code": 500,
"message": "获取旋转角度失败",
"data": null
}

15. 打开App

功能说明:打开指定云机上的App

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/open_app

请求参数

参数名必选类型说明
namestring云机容器名称
pkgstring包名

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/open_app" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"pkg": "com.example.app"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "打开App失败",
"data": null
}

16. 停止App

功能说明:停止指定云机上的App

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/stop_app

请求参数

参数名必选类型说明
namestring云机容器名称
pkgstring包名

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/stop_app" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"pkg": "com.example.app"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "停止App失败",
"data": null
}

17. 执行Shell命令

功能说明:在指定云机内执行Shell命令

请求方式:POST

请求URL

http://{主机IP}:8000/rpa/shell

请求参数

参数名必选类型说明
namestring云机容器名称
cmdstringShell命令
timeoutinteger超时秒数

请求示例

curl -X POST "http://192.168.99.108:8000/rpa/shell" \
-H "Content-Type: application/json" \
-d '{
"name": "android-01",
"cmd": "ls /sdcard",
"timeout": 10
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"output": "命令输出内容"
}
}

失败返回

{
"code": 500,
"message": "执行Shell命令失败",
"data": null
}

十六、M50管理

1. 查询M50设备详情

功能说明:查询M50算力卡设备详情信息

请求方式:GET

请求URL

http://{主机IP}:8000/lm/m50/device

请求参数

参数名必选类型说明
device_idinteger设备ID

请求示例

curl "http://192.168.99.108:8000/lm/m50/device?device_id=1"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "查询M50设备详情失败",
"data": null
}

2. 查询M50 DDR信息

功能说明:查询M50算力卡DDR内存信息

请求方式:GET

请求URL

http://{主机IP}:8000/lm/m50/ddr

请求参数

参数名必选类型说明
device_idinteger设备ID

请求示例

curl "http://192.168.99.108:8000/lm/m50/ddr?device_id=1"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "查询M50 DDR信息失败",
"data": null
}

3. 查询M50频率

功能说明:查询M50算力卡当前频率

请求方式:GET

请求URL

http://{主机IP}:8000/lm/m50/frequency

请求参数

参数名必选类型说明
device_idinteger设备ID

请求示例

curl "http://192.168.99.108:8000/lm/m50/frequency?device_id=1"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "查询M50频率失败",
"data": null
}

4. 设置M50频率

功能说明:设置M50算力卡目标频率

请求方式:POST

请求URL

http://{主机IP}:8000/lm/m50/frequency

请求参数

参数名必选类型说明
device_idinteger设备ID
typestring频率类型
frequencyinteger目标频率(Hz)

请求示例

curl -X POST "http://192.168.99.108:8000/lm/m50/frequency" \
-H "Content-Type: application/json" \
-d '{
"device_id": 1,
"type": "core",
"frequency": 800000000
}'

成功返回

{
"code": 0,
"message": "设置成功",
"data": null
}

失败返回

{
"code": 500,
"message": "设置M50频率失败",
"data": null
}

5. 查询M50 DVFS模式

功能说明:查询M50算力卡当前DVFS(动态电压频率调节)模式

请求方式:GET

请求URL

http://{主机IP}:8000/lm/m50/dvfs

请求参数

参数名必选类型说明
device_idinteger设备ID

请求示例

curl "http://192.168.99.108:8000/lm/m50/dvfs?device_id=1"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "查询M50 DVFS模式失败",
"data": null
}

6. 设置M50 DVFS模式

功能说明:设置M50算力卡DVFS(动态电压频率调节)模式

请求方式:POST

请求URL

http://{主机IP}:8000/lm/m50/dvfs

请求参数

参数名必选类型说明
device_idinteger设备ID
modeintegerDVFS模式 (0=performance,1=ondemand,2=userspace,3=independent)

请求示例

curl -X POST "http://192.168.99.108:8000/lm/m50/dvfs" \
-H "Content-Type: application/json" \
-d '{
"device_id": 1,
"mode": 0
}'

成功返回

{
"code": 0,
"message": "设置成功",
"data": null
}

失败返回

{
"code": 500,
"message": "设置M50 DVFS模式失败",
"data": null
}

7. 查询M50功耗/电压

功能说明:查询M50算力卡功耗和电压信息

请求方式:GET

请求URL

http://{主机IP}:8000/lm/m50/power

请求参数

参数名必选类型说明
device_idinteger设备ID

请求示例

curl "http://192.168.99.108:8000/lm/m50/power?device_id=1"

成功返回

{
"code": 0,
"message": "ok",
"data": {}
}

失败返回

{
"code": 500,
"message": "查询M50功耗电压失败",
"data": null
}

十七、网盘

1. 列出网盘文件列表

功能说明:列出网盘文件列表

请求方式:GET

请求URL

http://{主机IP}:8000/netdisk/list

请求参数

参数名必选类型说明
pathstring目录路径(相对于网盘根目录),默认为根目录

请求示例

curl "http://192.168.99.108:8000/netdisk/list?path=/"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"count": 2,
"list": [
{
"name": "backup.zip",
"size": "1024MB",
"isDir": false,
"mtimestamp": 1699876543,
"path": "/backup.zip"
},
{
"name": "data",
"size": "",
"isDir": true,
"mtimestamp": 1699876000,
"path": "/data"
}
]
}
}

返回字段说明

字段类型说明
countinteger文件总数
namestring文件/目录名
sizestring文件大小(目录为空)
isDirboolean是否为目录
mtimestampinteger修改时间戳
pathstring相对路径

失败返回

{
"code": 500,
"message": "列出网盘文件列表失败",
"data": null
}

2. 从网盘下载文件

功能说明:从网盘下载文件

请求方式:GET

请求URL

http://{主机IP}:8000/netdisk/download

请求参数

参数名必选类型说明
pathstring文件路径(相对于网盘根目录)

请求示例

curl "http://192.168.99.108:8000/netdisk/download?path=/backup.zip"

成功返回:文件内容(二进制流)

失败返回

{
"code": 500,
"message": "下载文件失败",
"data": null
}

3. 上传文件到网盘

功能说明:上传文件到网盘

请求方式:POST

请求URL

http://{主机IP}:8000/netdisk/upload

Content-Typemultipart/form-data

请求参数

参数名必选类型说明
pathstring目标路径(相对于网盘根目录),如 folder/sub.txt
filefile要上传的文件

请求示例

curl -X POST "http://192.168.99.108:8000/netdisk/upload" \
-F "path=/folder/upload.txt" \
-F "file=@local_file.txt"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"name": "upload.txt",
"size": "1KB",
"path": "/folder/upload.txt"
}
}

失败返回

{
"code": 500,
"message": "上传文件失败",
"data": null
}

4. 创建目录

功能说明:在网盘创建目录

请求方式:POST

请求URL

http://{主机IP}:8000/netdisk/mkdir

请求参数

参数名必选类型说明
pathstring目录路径(相对于网盘根目录)

请求示例

curl -X POST -H "Content-Type: application/json" \
-d '{"path": "/new_folder"}' \
"http://192.168.99.108:8000/netdisk/mkdir"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"path": "/new_folder"
}
}

失败返回

{
"code": 500,
"message": "创建目录失败",
"data": null
}

5. 删除文件或目录

功能说明:删除网盘中的文件或目录

请求方式:DELETE

请求URL

http://{主机IP}:8000/netdisk/delete

请求参数

参数名必选类型说明
pathstring文件/目录路径(相对于网盘根目录)

请求示例

curl -X DELETE "http://192.168.99.108:8000/netdisk/delete?path=/backup.zip"

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "删除失败",
"data": null
}

6. 移动或重命名文件

功能说明:移动或重命名网盘中的文件/目录

请求方式:POST

请求URL

http://{主机IP}:8000/netdisk/move

请求参数

参数名必选类型说明
oldPathstring原路径(相对于网盘根目录)
newPathstring新路径(相对于网盘根目录)

请求示例

curl -X POST -H "Content-Type: application/json" \
-d '{
"oldPath": "/old_name.txt",
"newPath": "/new_name.txt"
}' \
"http://192.168.99.108:8000/netdisk/move"

成功返回

{
"code": 0,
"message": "ok",
"data": null
}

失败返回

{
"code": 500,
"message": "移动/重命名失败",
"data": null
}

十八、魔云腾VPN

1. 安装VPN客户端

功能说明:在设备上安装魔云腾VPN客户端

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpn/install

请求参数

参数名必选类型说明
rabbet_idstring设备唯一身份标识(OSS rabbet ID),不传时自动取 deviceId
device_typestring设备型号(Q1/P1/R1/R1S/R1P/r1q等),不传时自动取 model 前缀

请求示例

curl -X POST "http://192.168.99.108:8000/mytVpn/install" \
-H "Content-Type: application/json" \
-d '{
"rabbet_id": "MYT-P1-001",
"device_type": "P1"
}'

成功返回

{
"code": 0,
"message": "ok",
"data": {
"message": "安装成功"
}
}

返回字段说明

字段类型说明
messagestring安装结果

失败返回

{
"code": 500,
"message": "安装VPN客户端失败",
"data": null
}

注意事项

  • rabbet_id 和 device_type 为可选参数,不传时将自动获取设备信息
  • 安装过程可能需要较长时间,请耐心等待

2. 启动VPN客户端

功能说明:启动设备上的魔云腾VPN客户端

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpn/start

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/mytVpn/start"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"message": "启动成功"
}
}

返回字段说明

字段类型说明
messagestring启动结果

失败返回

{
"code": 500,
"message": "启动VPN客户端失败",
"data": null
}

注意事项

  • 启动前请确保VPN客户端已安装

3. 停止VPN客户端

功能说明:停止设备上的魔云腾VPN客户端

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpn/stop

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/mytVpn/stop"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"message": "停止成功"
}
}

4. 卸载VPN客户端

功能说明:卸载设备上的魔云腾VPN客户端

请求方式:POST

请求URL

http://{主机IP}:8000/mytVpn/uninstall

请求参数:无

请求示例

curl -X POST "http://192.168.99.108:8000/mytVpn/uninstall"

成功返回

{
"code": 0,
"message": "ok",
"data": {
"message": "卸载成功"
}
}

返回字段说明

字段类型说明
messagestring卸载结果

失败返回

{
"code": 500,
"message": "卸载VPN客户端失败",
"data": null
}

注意事项

  • 卸载前建议先停止VPN客户端
  • 卸载操作不可恢复

附录

错误码说明

错误码说明
0成功
400请求参数错误
401未授权/认证失败
404资源不存在
500服务器内部错误

常见问题

  1. 接口返回401错误

    • 检查是否开启了接口认证
    • 确认认证信息是否正确
  2. 云机创建失败

    • 检查镜像是否已拉取到本地
    • 确认实例序号是否被占用
    • 检查磁盘空间是否充足
  3. 无法连接设备

    • 确认设备IP地址是否正确
    • 检查网络连接是否正常
    • 确认端口8000是否开放