Skip to content

RPC设备控制协议说明

1. 文档目的

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

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

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

2. 协议概览

2.1 两类传输路径

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

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

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

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

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

2.2 统一业务包体

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

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。请求头示例:

http
X-Authorization: Bearer eyJhbGciOi...

说明:

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

设备本地 HTTP 服务

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

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

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

成功示例:

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

后续请求示例:

http
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。

示例:

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说明
pingnull"pong"连通性检测

5.2 状态与诊断

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

getPlayerStatus 返回体中常见字段:

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

5.3 用户交互 / 中控按键

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

当前稳定推荐的 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_castnull{"force": true}"updateAuth""OK"刷新节目排期,支持强制刷新
updateDevicenull"OK"刷新设备信息
installApp{"url": "...", "desc": "..."}"OK"触发设备下载安装包,通常用于 Android 终端

说明:

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

5.6 高级编辑命令

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

说明:

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

6. 保留/内部命令

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

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

原因通常包括:

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

7. 调用示例

7.1 云端查询设备状态

bash
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
    }
  }'

示例响应:

json
{
  "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 云端发送遥控返回键

bash
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 云端获取截图

bash
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 云端获取日志并按关键字过滤

bash
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 云端修改设置

bash
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

先登录:

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

再调用:

bash
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,报文内容如下:

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

示例响应:

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

7.8 UDP 直连发送遥控返回键

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

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

7.9 UDP 直连查询设备状态

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

json
{
  "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 服务的实际实现整理。

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