RPC设备控制协议说明

1. 文档目的

本文档面向第三方中控、集成平台和运维工具开发人员,说明本系统当前支持的两类设备控制方式:

  • 服务器转发 RPC:管理端通过云端或私有化服务器,将命令转发到指定设备
  • UDP 直连控制:第三方中控直接向设备局域网地址发送 UDP 命令

本文档只描述当前代码中已经实现并可确认的协议能力,不扩展未落地的控制方式。

2. 协议概览

2.1 两类传输路径

本系统当前支持两类设备控制链路:

  1. 服务器转发 RPC
    管理端先调用服务器接口,再由服务器将指令转发给设备。

  2. UDP 直连控制
    第三方中控直接向设备本地开放的 UDP 端口发送命令,不经过服务器转发。

这两类方式在业务层复用同一套命令包体,区别只在传输层:

  • HTTP RPC 走服务器或设备本地 HTTP 服务
  • UDP 走设备本地 UDP 端口

2.2 统一业务包体

本系统的设备控制命令统一采用 RpcCmd JSON 包体:

{
  "method": "getPlayerStatus",
  "params": {
    "t": "q",
    "idx": 1,
    "p": null,
    "v": null
  }
}

字段说明:

  • method: 命令名称
  • params.t: 报文类型
  • params.idx: 可选请求序号,便于调用方匹配请求和响应
  • params.p: 已废弃,不建议使用
  • params.v: 业务参数或业务返回值

params.t 当前含义:

  • q: 请求
  • s: 成功响应
  • se: 业务失败响应
  • sd: 已处理响应,主要用于内部转发确认,第三方通常不需要依赖

建议第三方只使用以下核心字段:

  • method
  • params.t
  • params.idx
  • params.v

3. 服务器转发 RPC

3.1 云端两段式 RPC

适用于联网投放或云端私有化部署场景。

  • 端点: POST https://api.example.com:9292/api/rpc/twoway/{deviceId}
  • 鉴权: X-Authorization: Bearer <jwt>
  • 说明: 管理端将命令发送给服务器,服务器再转发给目标设备,并等待设备返回业务结果

适合:

  • 查询设备状态
  • 截图
  • 获取日志
  • 修改设置

3.2 云端单向 RPC

  • 端点: POST https://api.example.com:9292/api/rpc/oneway/{deviceId}
  • 鉴权: X-Authorization: Bearer <jwt>
  • 说明: 只负责发送,不等待设备业务返回

适合:

  • 批量刷新
  • 尽力送达型中控指令

3.3 私有化 / 局域网 HTTP 直连

适用于管理端与设备处于同一局域网,或私有化环境下直接访问设备本地 HTTP 服务。

  • 登录端点: POST http://192.168.1.100:9393/api/nauth/login
  • RPC 端点: POST http://192.168.1.100:9393/api/device/rpc/{deviceId}
  • 鉴权: X-Authorization: Bearer <token>

说明:

  • 设备本地 HTTP 服务默认端口为 9393
  • 局域网登录成功后会返回本地 JWT
  • 后续 /api/* 请求均需携带 JWT

3.4 鉴权方式

云端 / 私有化管理端

云端 RPC 使用管理端 JWT。请求头示例:

X-Authorization: Bearer eyJhbGciOi...

说明:

  • X-Authorization 为当前客户端默认使用的头
  • 服务端同时兼容 Authorization
  • JWT 获取方式与管理端登录体系一致,本文不展开登录流程本身
设备本地 HTTP 服务

局域网服务支持无鉴权登录接口:

POST http://192.168.1.100:9393/api/nauth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "your-local-password"
}

成功示例:

{
  "token": "eyJhbGciOi..."
}

后续请求示例:

X-Authorization: Bearer eyJhbGciOi...

3.5 常见 HTTP 返回

云端 RPC
  • 200 OK: 请求成功送达,且两段式 RPC 已收到设备响应
  • 401 Unauthorized: 未登录或 token 无效
  • 403 Forbidden: 已登录但无权操作该设备
  • 504 Gateway Timeout: 设备离线、超时或未及时返回
设备本地 HTTP RPC
  • 200 OK: HTTP 层调用成功,业务是否成功以 params.t 为准
  • 401 Unauthorized: 未携带有效 JWT
业务判断建议

第三方集成时,不要只看 HTTP 状态码,还要同时判断:

  • params.t == "s": 业务成功
  • params.t == "se": 业务失败

3.6 关于服务器附加字段

云端 /api/rpc/twoway/*/api/rpc/oneway/* 这类服务器转发 RPC 在实现上还可能支持 timeoutpersistentexpirationTimeretriesadditionalInfo 等顶层字段。

但为了兼容云端与局域网两种模式,第三方默认应只发送本文档的业务包体:

  • method
  • params

除非部署方已明确限制为云端模式,否则不建议依赖云端特有的持久化 RPC 字段。

4. UDP 直连控制

4.1 适用方式

UDP 是设备本地直接开放的控制入口,不经过云端或私有化服务器转发。

第三方中控可以直接向设备局域网地址发送 UDP 数据报,例如:

  • 192.168.1.120:9393

这类方式更适合中控设备、控制主机或局域网自动化系统。

4.2 监听端口

设备本地 UDP 服务与本地 HTTP 服务使用同一端口:

  • 9393

因此,第三方中控只需要知道设备的局域网 IP 和端口即可发起控制。

4.3 UDP 报文格式

UDP 传输的业务内容仍然是同一套 RpcCmd JSON。

示例:

{
  "method": "ping",
  "params": {
    "t": "q",
    "idx": 1001,
    "p": null,
    "v": null
  }
}

说明:

  • UDP 请求包体与 HTTP RPC 的 data 内容完全一致
  • UDP 响应包体也仍然是 RpcCmd JSON
  • 设备会将响应回发到发送方的源地址和源端口
  • UDP 模式不需要 deviceId URL,也不经过服务器路由

4.4 安全边界

当前 UDP 接收链路未体现额外的 HTTP/JWT 鉴权层,因此只能视为受信任局域网内部协议。

强烈建议:

  • 仅在受信任内网中启用和使用
  • 不要暴露到公网
  • 不要通过公网穿透直接开放该端口

4.5 中控推荐用法

第三方中控接入时,优先建议使用 UDP 直连。

推荐通过 UDP 发送的小报文、低延迟控制:

  • ping
  • remoter
  • update_cast
  • getPlayerStatus

推荐优先通过 HTTP RPC 发送的大报文或更依赖稳定返回的能力:

  • getScreenshot
  • getLog

说明:

  • 上述是推荐用法,不是实现限制
  • 某些命令在 UDP 上理论上也能发送,但从工程稳定性看,不建议把大体积返回长期依赖在 UDP 上

5. 统一命令参考

下面只列出当前设备侧明确实现并适合第三方依赖的命令。

5.1 基础连通性

方法 请求 params.v 响应 params.v 说明
ping null "pong" 连通性检测

5.2 状态与诊断

方法 请求 params.v 响应 params.v 说明
getPlayerStatus null Map 查询设备当前状态
getScreenshot nullint String 返回 Base64 截图;若传整数则表示截图最大字节目标,缺省约 49000
getLog {"count": 100, "textSearch": "error"} {"log": "..."} 获取设备日志,支持条数和关键字过滤
clearLog null "OK" 清空设备日志
getAuthLoc null {"authToken": "..."} 获取设备本地授权信息,主要用于 LAN 相关能力

getPlayerStatus 返回体中常见字段:

  • ver: 设备端应用版本
  • info: 设备摘要信息
  • curTs: 设备当前时间戳
  • curMHCast: 当前节目摘要
  • curPlay: 当前播放关系信息
  • taskLen: 当前排期长度
  • playTaskList: 当前排期前若干项
  • httpServerInfo: 设备本地 HTTP 服务信息

5.3 用户交互 / 中控按键

方法 请求 params.v 响应 params.v 说明
remoter String true 向设备注入一个遥控/按键事件

当前稳定推荐的 remoter 键值:

  • 方向键: up down left right
  • 确认/返回: select back
  • 数字键: 09
  • 快进快退: forward backward

说明:

  • 这些键值会在设备侧转换成标准键盘语义,例如方向键、返回键、数字键
  • 其他自定义字符串也可能被事件流接收,但第三方不建议依赖未约定的自定义键值

5.4 设置与执行

方法 请求 params.v 响应 params.v 说明
getSettings "key" 任意类型 读取单个设置项
setSettings {"key": value} true/false 批量写入一个或多个设置项
execCmd {"method": "xxx", "params": ...} 任意类型 调用设备端已注册的设置执行命令

说明:

  • getSettingsparams.v 一般传单个键名
  • setSettings 支持一次提交多个键值对
  • execCmd 适合执行设置模块已暴露的动作型命令,具体 method 取值需由部署方确认

5.5 播放刷新与升级

方法 请求 params.v 响应 params.v 说明
update_cast null{"force": true}"updateAuth" "OK" 刷新节目排期,支持强制刷新
updateDevice null "OK" 刷新设备信息
installApp {"url": "...", "desc": "..."} "OK" 触发设备下载安装包,通常用于 Android 终端

说明:

  • update_cast 最常见用法为 null{"force": true}
  • installApp 只是发起安装流程,最终成功与否受设备平台、下载地址、安装权限影响

5.6 高级编辑命令

方法 请求 params.v 响应 params.v 说明
editCast 节目 JSON 或 patch JSON true 远程修改节目内容
editMedia 素材补丁 JSON true 远程修改节目中的某个素材参数

说明:

  • 这两类命令会直接修改节目数据
  • editCast 支持完整覆盖,也支持 editMode = "patch" 的递归补丁方式
  • editMedia 依赖节目内部素材结构,通常需要准确的 eid 或目标节目上下文
  • 这两类命令只建议给深度集成方使用,不建议作为通用中控协议的基础能力

6. 保留/内部命令

下面这些常量虽然存在于代码中,但当前不建议第三方按公开稳定接口依赖:

  • getDeviceSelf
  • getMHCastRelationList
  • postAttrs
  • lanAuth
  • jumpTo
  • mhtRpc
  • sync
  • deleteDeviceBySelf
  • postSyncInfo

原因通常包括:

  • 仅供设备内部链路或调试链路使用
  • 参数结构耦合内部实现
  • 未来更容易调整,不适合作为第三方中控协议的稳定承诺

7. 调用示例

7.1 云端查询设备状态

curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "getPlayerStatus",
    "params": {
      "t": "q",
      "idx": 1,
      "p": null,
      "v": null
    }
  }'

示例响应:

{
  "method": "getPlayerStatus",
  "params": {
    "t": "s",
    "idx": 1,
    "p": null,
    "v": {
      "ver": "1.2.3",
      "info": "Device-A / Android",
      "curTs": 1775179200000,
      "taskLen": 6,
      "httpServerInfo": {
        "state": 1,
        "localAddr": "http://192.168.1.120:9393"
      }
    }
  }
}

7.2 云端发送遥控返回键

curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "remoter",
    "params": {
      "t": "q",
      "idx": 2,
      "p": null,
      "v": "back"
    }
  }'

7.3 云端获取截图

curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "getScreenshot",
    "params": {
      "t": "q",
      "idx": 3,
      "p": null,
      "v": 49000
    }
  }'

成功后 params.v 为 Base64 图片字符串。

7.4 云端获取日志并按关键字过滤

curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "getLog",
    "params": {
      "t": "q",
      "idx": 4,
      "p": null,
      "v": {
        "count": 100,
        "textSearch": "error"
      }
    }
  }'

7.5 云端修改设置

curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "setSettings",
    "params": {
      "t": "q",
      "idx": 5,
      "p": null,
      "v": {
        "debugMode": 1,
        "httpServerEnable": true
      }
    }
  }'

7.6 局域网登录并调用设备 HTTP RPC

先登录:

curl -X POST "http://192.168.1.100:9393/api/nauth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin",
    "password": "your-local-password"
  }'

再调用:

curl -X POST "http://192.168.1.100:9393/api/device/rpc/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <token>" \
  -d '{
    "method": "ping",
    "params": {
      "t": "q",
      "idx": 6,
      "p": null,
      "v": null
    }
  }'

7.7 UDP 直连发送 ping

发送 UDP 数据报到设备,例如 192.168.1.120:9393,报文内容如下:

{
  "method": "ping",
  "params": {
    "t": "q",
    "idx": 1001,
    "p": null,
    "v": null
  }
}

示例响应:

{
  "method": "ping",
  "params": {
    "t": "s",
    "idx": 1001,
    "p": null,
    "v": "pong"
  }
}

7.8 UDP 直连发送遥控返回键

发送到 192.168.1.120:9393 的报文示例:

{
  "method": "remoter",
  "params": {
    "t": "q",
    "idx": 1002,
    "p": null,
    "v": "back"
  }
}

7.9 UDP 直连查询设备状态

发送到 192.168.1.120:9393 的报文示例:

{
  "method": "getPlayerStatus",
  "params": {
    "t": "q",
    "idx": 1003,
    "p": null,
    "v": null
  }
}

8. 可选的批量单向广播

如果第三方平台需要对一组设备广播同一条命令,可使用管理端提供的扩展接口。

支持的端点:

  • POST https://api.example.com:9292/api/mht/oneway/device/ids?ids=<id1>,<id2>
  • POST https://api.example.com:9292/api/mht/oneway/asset/ids?ids=<assetId1>,<assetId2>
  • POST https://api.example.com:9292/api/mht/oneway/customer/ids?ids=<customerId1>,<customerId2>
  • POST https://api.example.com:9292/api/mht/oneway/tenant

说明:

  • 请求体仍然是同一套 RpcCmd JSON
  • 这类接口是单向广播,不返回每台设备的业务结果
  • 适合批量触发 update_cast、刷新状态或简单控制命令

9. 第三方接入建议

9.1 推荐优先级

  1. 第三方中控优先使用 UDP 直连
  2. 设备状态查询优先使用 getPlayerStatus
  3. 中控按键优先使用 remoter
  4. 排期刷新优先使用 update_cast
  5. 截图和日志优先通过 HTTP RPC 获取

9.2 稳定性建议

  • 所有请求都带 idx,便于日志与回调对账
  • 业务成功以 params.t == "s" 为准,不要只看 HTTP 200
  • remoter 只使用本文档列出的稳定键值
  • editCasteditMedia 只建议在联合调试后开放
  • 云端模式下建议优先用 twoway,便于调用方拿到明确反馈
  • 大体积返回场景不建议长期依赖 UDP

9.3 安全建议

  • 不要在第三方系统中长期明文保存高权限 JWT
  • 若仅需要控制部分设备,应使用最小权限账号
  • 设备安装、节目编辑类命令应做操作审计
  • UDP 端口只应暴露在受信任局域网中

10. 版本说明

本文档基于当前仓库中本系统管理端、设备端和本地 HTTP / UDP 服务的实际实现整理。

如需对接未列出的内部命令,建议先与部署方确认目标版本和可用范围,再进入联合调试。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐