主题
7.1 WebSocket 服务配置
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 里发写入报文。