MQTT 客户端
网关以客户端方式向外发起连接,订阅 / 发布外部 IIoT broker(HiveMQ / Mosquitto / EMQX / AWS IoT / Azure IoT Hub 等)的 topic。到达的消息保存在内存缓存中,标签在每个采集周期读取缓存值。
| 场景 | 应使用哪种模式 |
|---|---|
| 外部 IT 系统通过 REST POST 发送数值时 | HTTP 推送 |
| 外部服务器通过 WebSocket 推送时 | WebSocket 客户端 |
| 外部 IIoT MQTT broker 通过 topic 推送时 | MQTT 客户端(本页) |
| Sparkplug B 标准(NBIRTH/DBIRTH/DCMD) | Sparkplug B |
| 直接读取厂内 PLC 数值时 | Modbus / OPC-UA 等 |
注册表单输入项
| 输入栏 | 填写内容 | 示例 |
|---|---|---|
| IP 地址 | MQTT broker 主机 | broker.hivemq.com, 10.0.0.50 |
| 端口 | MQTT broker 端口(明文 1883,TLS 8883) | 1883, 8883 |
| USERNAME | broker 认证用户名(可选) | iotuser |
| PASSWORD | broker 认证密码(可选) | s3cret |
| TLS | 选择明文 / TLS | false (tcp) / true (ssl) |
| QoS | 订阅 / 发布 QoS | 0 / 1 / 2 |
| KEEP ALIVE | keep-alive 周期(秒) | 60 |
| CLEAN SESSION | clean session 标志 | true(默认) / false |
| CLIENT ID | 显式指定 client id(可选) | edge-plant-01 |
| 采集周期 | 网关读取缓存值的周期(ms) | 1000 |
实际 broker URL:<scheme>://<host>:<port>(例如:tcp://broker.hivemq.com:1883、ssl://10.0.0.50:8883)。
未指定 CLIENT ID 时,将按 PP-<opc_id>-<random6> 格式自动生成(符合 MQTT v3.1 建议的 23 字符长度限制)。
标签的 PLC 地址表示法 — 4-mode JSON
标签的 PLC 地址 = MQTT topic + 4-mode JSON 解码器。与 WebSocket / Apache Kafka 采用相同规范。
| 模式 | 格式 | 行为 |
|---|---|---|
| SCALAR | factory/line1/temp 或 factory/line1/temp.value | 将整条消息作为 String。若消息为 JSON object,则回退为 raw。 |
| KEY | sensors/multi:temperature | 取 top-level JSON key 的值(例如:{"temperature":25.3,"humidity":60} → 25.3) |
| PATH | sensors/multi:$.data.tags.T1 | JSON Pointer 动态求值(支持嵌套 key) |
| RAW | sensors/multi:_raw_ | 最后一条完整消息(调试用) |
同样支持 Wildcard 订阅:
| 标签的 PLC 地址 | 含义 |
|---|---|
device/+/status | 单层 wildcard(sensor01/sensor02/... 全部) |
factory/# | 多层 wildcard(factory 下全部 — 以最后到达的消息优先) |
read 的首次调用为 lazy subscribe(返回空字符串)。从下一个轮询周期开始返回缓存值。
常用场景
| 场景 | 做法 |
|---|---|
| HiveMQ Cloud / public broker | host = broker.hivemq.com,1883(明文),8883(TLS+认证) |
| 厂内 Mosquitto / EMQX | host = 厂内 IP,1883 / 8883。注册 username/password 等 |
| AWS IoT Core | host = <account>-ats.iot.<region>.amazonaws.com,8883 + X.509(需另行配置 truststore) |
| Azure IoT Hub | host = <hub>.azure-devices.net,8883 + SAS 令牌(username/password) |
| 保证 QoS=1 | 选择 QoS=1 — broker 会重发直至收到 ack。处理开销 ↑ |
| 持久会话 | CLEAN SESSION=false + 固定 CLIENT ID — broker 会保存未接收的消息 |
write(publish)
在标签页面或通过 REST API 写入数值时,会立即向 broker 的对应 topic 发布(retain=false)。value 的 String 将原样作为 payload 发送 — JSON / 纯文本均可。
plc_address = factory/line1/cmd
value = ON
→ MQTT publish: topic="factory/line1/cmd" payload="ON"
plc_address = devices/dev01/setpoint
value = {"sp":42.5,"unit":"degC"}
→ MQTT publish: topic="devices/dev01/setpoint" payload='{"sp":42.5,"unit":"degC"}'
常见问题与解决
| 现象 | 原因 | 解决 |
|---|---|---|
| 收不到数值 | broker 未发布消息 | 用 mosquitto_sub -h <host> -p 1883 -t '<topic>' -v 直接接收,确认是否有输出 |
[MQTT] connect 실패: not authorized | username/password 错误 | 重新确认 broker 用户名/密码。检查 ACL 限制 |
[MQTT] connect 실패: timeout | 防火墙 / 端口被阻断 | 用 telnet <host> 1883、openssl s_client -connect <host>:8883 验证 |
| TLS 握手失败 | 自签名证书 / cacerts 缺失 | 生产环境建议使用正式证书。临时情况请联系系统管理员添加 truststore |
| Wildcard 只收到一次 | wildcard 以最后到达的消息优先 | 按 topic 分别注册(每个 topic 单独建标签) |
更详细的技术文档
- 高级 — 驱动:MQTT 客户端
- Sparkplug B(MQTT + 标准 NBIRTH/DBIRTH/DCMD 负载)
- Eclipse Paho 官方文档