WebSocket 与消息通知
约 1265 字大约 4 分钟
2026-10-16
独立应用也能接收平台推送:设备属性、上下线、告警、站内通知均不要求私有平台源码。平台路线说明 Hub 和权限的实现,本页说明应用怎样接入已有能力。
已有实现与当前边界
| 端 | 使用入口 |
|---|---|
| Vue Web | ur-kit 的 WsClient、acquireSharedWsClient / releaseSharedWsClient |
| uni-app | mobile 的 RealtimeService、WebSocketProvider 与 eventBus |
| Go / Java / Node 后端 | 使用 WebSocket 传输库,按同一公开频道协议接入 |
Go/Java/Node 当前 SDK 封装 HTTP/RPC,尚无各自专用 WS 高层客户端;OpenAPI 生成的 connect 方法不是 WS 连接器。业务后端可按本页协议使用运行库,也可使用 Hook 接收设备事件。
连接、认证与代理
WS 入口为 GET /api/v1/system/common/websocket/connect,平台 HTTP(S) 根地址换成 WS(S)。浏览器不能任意设置握手头,当前平台允许查询串提供 token 及 app-id、tenant-code、project-id、device-id;后端传输库可用请求头。
生产使用 TLS,并隐藏访问日志中的 token 查询串。企业/项目选择不是授权证明,平台继续检查每个订阅的目标资源。
开发:浏览器 → Vite /api(ws: true)→ 应用 Go 代理 → 平台 WS
生产:浏览器 → 应用 Go 代理 → 平台 WSv0.2.36 的 Vite 配置未启用 WS 转发,使用该标签开发实时页面时,在 apps/iot-basic/web/vite.config.mts 的 /api 代理补 ws: true。本次 ur-kit 源码修复已包含这项配置;SDK 标签不会被追改。外层 Nginx/其他入口也要支持 Upgrade。
Web 与移动端复用
v0.2.36 可从 @vben/saas 包根导入;本次更新新增无 UI 依赖的 @vben/saas/ws-client 窄入口,使用它需获取包含该入口的共享源码版本。
// v0.2.36 的兼容入口;新共享源码可改为 @vben/saas/ws-client。
import { acquireSharedWsClient, releaseSharedWsClient } from '@vben/saas';在应用壳层统一取得共享连接、管理 onConnected,等待确认后订阅设备频道;业务页面使用稳定回调并在退出时移除。不要每个组件建立一条连接,也不要反复覆盖连接级回调。完整装配示例见ur-kit 实时接入。
listen/unlisten 仅管理本地回调,适合服务端已自动订阅的用户通知;subscribe/unsubscribe 会发请求并等待平台确认。不要把监听本地回调当作已取得频道权限。
uni-app 复用 services/realtime.service.ts 与 providers/websocket.provider.ts,经 ws:device.property、ws:device.status、ws:user.notify 分发。页面退出清理监听,应用退出才统一关闭连接。切换企业、项目和登录身份后清理旧范围数据;令牌更新不代表已有连接身份立即刷新。
当前协议
等待 connected,发送一个频道:
{"id":1,"type":"subscribe","channel":"device.prop.DEMO.sensor1"}确认是 subscribe.ok,失败是带 code/msg 的 error;取消是 unsubscribe/unsubscribe.ok。服务端推送:
{
"type":"publish",
"channel":"device.prop.DEMO.sensor1",
"data":{
"device":{"productID":"DEMO","deviceName":"sensor1"},
"projectID":"9007199254740993",
"timestamp":"1792112400000",
"receivedTime":1792112400123,
"params":{"temperature":23},
"quality":{"temperature":"GOOD"}
}
}| 频道 | 内容 |
|---|---|
device.prop.<productID>.<deviceName> | 整包属性 |
device.prop.<productID>.<deviceName>.<identifier> | 单属性 |
device.conn.<productID>.<deviceName> | 上下线 |
device.event.<productID>.<deviceName>.<identifier> | 事件 |
device.action.<productID>.<deviceName>.<identifier> | 行为 |
device.ota.<productID>.<deviceName> | OTA |
project.prop.<projectID> / project.conn.<projectID> | 项目聚合 |
area.prop.<projectID>.<areaID> | 区域属性 |
user.notify.<userID> | 站内通知 |
sys.alarm.<tenantCode> | 企业告警 |
频道中的尖括号表示替换参数,实际请求不包含它们。每次请求只传 channel,不使用旧 up.sub/body.code,也不传 channels 数组。大整数 ID 保留字符串;timestamp 为字符串毫秒、receivedTime 为数字毫秒。
应用层心跳为 ping/pong;断线恢复订阅后再查询快照补齐数据。收到属性变化不一定意味着设备已执行控制,实际下行与回执另行验收。
应用发送自己的站内通知
应用后端可调用 POST /api/v1/system/notify/message/info/send,或公开 NotifyManage 的 MessageInfoSend RPC,由平台分发给用户。需要平台授予该操作权限,并提前配置 notifyCode 和渠道;普通订阅权不包含通知发送权。
{
"userIDs":["9007199254740993"],
"isGlobal":2,
"notifyCode":"<registered-notify-code>",
"subject":"业务处理完成",
"body":"请进入应用查看结果。"
}收件人由后端按实际业务范围计算,不允许前端任意群发。WS 提示、持久消息列表和已读状态是不同环节,重新登录后通过消息中心接口恢复记录。
任意自定义频道并无通用外部注册接口。需要新增平台频道时由平台维护者实现命名空间和授权;应用也可在自己的后端建立实时通道,无需导入私有 Hub。
验证
实际验证登录/过期认证、合法与越权订阅、上报推送、退订、通知发送、重连和身份切换。ur-kit 已提供客户端协议与本机真实 WS 代理测试,命令见实时接入指南;本机模拟通过不能代替目标平台或真实设备验收。
更新日志
2026/10/16 20:08
查看所有更新日志
b1437-docs(应用开发): 补齐WS通知及平台能力接入导航于
