Skip to content

7.1 WebSocket 服务配置 ​

WebSocket vs HTTP 轮询,以及 /ws 复用端口、wss 混合内容、认证在订阅报文里三个要点

WebSocket 是获取实时数据点变化的推荐方式:服务器主动推送,不用轮询。

7.1.1 服务说明 ​

项值
路径/ws
WS 地址ws://{服务器IP}/ws(端口 80)
WSS 地址wss://{服务器域名}/ws(端口 443)
是否需要额外开端口不需要,复用 HTTP/HTTPS 端口

HTTPS 页面必须用 wss://

浏览器的 Mixed Content 策略会阻断 HTTPS 页面里的 ws:// 连接(抛 SecurityError)。反过来,HTTP 页面用 wss:// 会因证书问题连不上。正确做法是按当前页面协议自动选择:

javascript
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:'
const url = `${protocol}//${location.host}/ws`

7.1.2 认证方式 ​

没有 Token,也不使用 URL 参数。认证信息随每一条业务报文一起发送,username/password 明文放在 JSON 里。

不存在 ?token= 这种写法

ws://ip/ws?token=xxx 是无效的,服务器不解析 URL 上的任何认证参数。连接握手阶段不做认证,认证发生在发送订阅报文时。

7.1.3 订阅报文 ​

连接建立后发送订阅报文,字段名如下(操作名字段是 cmd,和 HTTP 接口一致):

json
{
  "cmd": "subscribe",
  "username": "linpan",
  "password": "你的密码",
  "project": "main",
  "datas": ["车间1/1号机/温度", "车间1/1号机/湿度", "server/online/PLC/11315751"]
}
字段说明
cmd固定为 subscribe
username / password账号认证,与 HTTP 接口一致
project项目名,一般为 main
datas要订阅的数据点名数组,可包含 主键/子键 形式

订阅的数据点变化后,服务器就会推送过来。要改订阅列表时重新发一条完整的 subscribe 报文即可,以最后一次为准。

7.1.4 推送报文 ​

服务器推送的是一个 JSON 数组,每个元素为 {name, value}:

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

要点:

  • 是数组,不是单个对象,一次可能带回多个点的变化
  • value 是字符串,数值比较前需先转换类型
  • 没有时间戳字段。需要时间信息时使用收到消息的本地时间,或通过 HTTP 历史接口查询
  • 只推送变化的点,值没变不会推

7.1.5 最小可用示例 ​

javascript
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:'
const ws = new WebSocket(`${protocol}//${location.host}/ws`)

ws.onopen = () => {
  ws.send(JSON.stringify({
    cmd: 'subscribe',
    username: 'linpan',
    password: '你的密码',
    project: 'main',
    datas: ['车间1/1号机/温度', '车间1/1号机/湿度'],
  }))
}

ws.onmessage = (e) => {
  const list = JSON.parse(e.data)
  if (!Array.isArray(list)) return
  list.forEach(({ name, value }) => {
    console.log(name, value)
  })
}

7.1.6 WebSocket 只负责项目变量 ​

云组态里三类变量使用的通道不同,这会直接影响对接方式:

变量类型通道
项目变量(无前缀,实时数据库数据点)WebSocket /ws 推送,断线时退回 HTTP get_real 轮询
设备变量(@设备ID.寄存器)HTTP plc_data_read 轮询,不走 WebSocket
MQTT 变量(#主题)浏览器直连 MQTT Broker,不走 /ws

所以:要通过 WebSocket 获取 PLC 寄存器的值,需先让数据进入实时数据库(见 3.1 五种上云方式总览)。

7.1.7 写数据要走 HTTP ​

WebSocket 通道只用于接收推送。要修改数据点,用 HTTP 的 set_real(见 4.3 实时数据接口),不要往 WebSocket 里发写入报文。


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