Skip to content

7.2 订阅与推送机制 ​

WebSocket 订阅与推送时序:握手 → 订阅 → 变化推送 → 心跳

7.2.1 完整流程 ​

  1. 客户端按当前页面协议建立 WebSocket 连接到 /ws(握手阶段不做认证)
  2. 客户端发送 cmd: "subscribe" 报文,带账号密码、项目名和数据点名数组
  3. 服务器校验账号后登记订阅关系
  4. 被订阅的数据点值发生变化时,服务器把变化打包成数组推送过来
  5. 连接断开时订阅关系失效,重连后必须重新发送订阅报文

7.2.2 报文格式 ​

订阅(字段名是 cmd 和 datas):

json
{
  "cmd": "subscribe",
  "username": "linpan",
  "password": "你的密码",
  "project": "main",
  "datas": ["车间1/1号机/温度", "车间1/1号机/湿度"]
}

推送(JSON 数组,元素为 {name, value}):

json
[
  { "name": "车间1/1号机/温度", "value": "25.6" }
]

修改订阅列表:没有单独的 unsubscribe 操作,直接重发一条完整的 subscribe 报文覆盖即可。

7.2.3 推送的触发条件 ​

只有值真的变了才推送。同一个值反复写入不会产生推送,所以:

  • 不要靠推送频率判断设备是否在线,用 server/online/... 状态点判断
  • 需要「即使不变也定时留一条」的记录,靠存盘方式实现(见 4.4 历史数据接口),不要靠 WebSocket

7.2.4 断线与降级 ​

WebSocket 断开后要做两件事:

  1. 重连:建议用指数退避(1s、2s、4s…上限 30s),避免服务器重启时所有客户端同时冲击
  2. 重新订阅:重连成功后必须重发 subscribe,订阅关系不会自动恢复

云组态前端的做法可以直接参考:WebSocket 掉线后自动退回 HTTP get_real 轮询保证数据不中断,WebSocket 恢复后再切回推送。对可靠性要求高的对接程序建议按此思路实现双通道。

7.2.5 写保护 ​

界面上刚点了按钮把某个点写成 1,服务器可能马上推来一条还是旧值 0 的消息(因为写入和推送有时序差),造成按钮显示回退到旧状态。

处理方式是加写保护窗口:本地写入后的一段时间内(云组态用 2 秒)忽略服务器推送的该点旧值,窗口结束后再接受推送。对接程序含控制类界面时,这一步不可省略。

7.2.6 性能建议 ​

  • 只订阅当前页面/当前业务真正需要的点,不要一次订阅几千个
  • 数据点名越长,推送报文越大,命名不要过度冗长
  • 高频变化的点(毫秒级)不适合直接推到浏览器,建议在设备侧或服务器侧先降频

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研