【鸿蒙优选三方库】@ohos/mqtt:设备与云之间那条一直在线的通道

IoT 消息为什么都走 MQTT?因为它的发布订阅模型天生适合"一对多、随时推、允许离线"。@ohos/mqtt 基于 Eclipse paho.mqtt.c,完整支持 MQTT V5 全属性,遗嘱机制让设备掉线自动上报,不用你写一行心跳检测代码。

📦 仓库地址 | ohpm install @ohos/mqtt | v2.0.30 | EPL-2.0


它解决什么问题

设备要"随时能收到云端指令、随时能把数据推上去",HTTP 轮询做不到——延迟高、费电、还没法主动推。自己写长连接?要处理断线重连、心跳保活、消息去重、离线缓存,全是坑。

MQTT 把这些都标准化了。@ohos/mqtt 基于 Eclipse paho.mqtt.c(MQTT 客户端的事实标准),封装成 ArkTS API。

最有价值的是遗嘱机制(LWT):连接时告诉 Broker"我要是突然断了,帮我发这条消息"。设备断网后 Broker 检测到心跳超时,自动替它发离线通知。订阅方立刻知道设备掉线了——零代码实现掉线检测。


核心能力

能力说明
MQTT 3.1.1 / 5.0两个主流版本全支持
V5 全属性Will / Publish / Subscribe / Unsubscribe / Disconnect 各自细粒度属性
QoS 0/1/2最多一次 / 至少一次 / 恰好一次
保留消息retained,新订阅者立刻拿到最新状态
遗嘱机制掉线自动发通知
断线重连自动重连 + 回调通知
多客户端一个 App 连多个 Broker

V5 的几个实用属性:messageExpiryInterval 让过期消息不再推送(限时通知很需要)、userProperties 给消息打标签而不改 payload、willDelayInterval 延迟发遗嘱避免网络抖动误报。


30 秒上手

import { MqttClient, MqttConnectOptions } from '@ohos/mqtt'

const client = new MqttClient({
  serverUrl: 'mqtt://broker.example.com:1883',
  clientId: 'device_001',      // 必须全局唯一
})

client.on('connect', () => {
  client.subscribe('/devices/001/cmd', { qos: 1 })
})
client.on('message', (topic, payload) => {
  console.info(`${topic}: ${payload.toString()}`)
})
client.on('connectionLost', (cause) => console.error('断开: ' + JSON.stringify(cause)))

const options: MqttConnectOptions = {
  userName: 'device',
  password: 'secret',
  cleanSession: false,        // 保留会话,离线消息不丢
  keepAliveInterval: 60,
  will: {                     // 遗嘱:掉线时 Broker 自动发这条
    topic: '/devices/001/status',
    payload: JSON.stringify({ online: false }),
    qos: 1,
  },
}
client.connect(options)

// 发布
client.publish('/devices/001/telemetry', JSON.stringify({ temp: 26.5 }), { qos: 1 })

社区已解决的典型问题

高频发布触发 UAF 崩溃(#495)
v2.0.29 在高频 publish 时,libmqttasync.so 在 MqttResponseComplete → BaseContext::GetCode() 路径出现 use-after-free。修复方式是在 native 侧 EventManager::Emit 期间持有锁防止数据竞争(#502)。高频场景务必升级到最新版并做压测。

批量发布 QoS 0 消息 crash(#497)
已修复。批量发送时仍建议限制单批数量、发送前校验 payload 大小。

connect 偶现崩溃(#498)
已修复。弱网环境下连接可能超时触发异常,建议设合理的 connectTimeout 和重连策略。

每隔 3 秒发消息,运行一段时间后报错(#499)
已修复。根因是 keepAliveInterval 与业务发送间隔不匹配,Broker 判定连接超时。经验值:心跳间隔设为业务消息间隔的 2~3 倍。


适合谁用

  • 智能家居 / 智能硬件:状态上报 + 指令下发
  • 车联网:位置、行驶数据、远程诊断
  • 工业设备监控:千级设备接入,QoS 分级保障
  • 即时消息推送:聊天、通知、弹幕
  • 需要 MQTT V5 高级特性:用户属性、消息过期、主题别名

266 个 Issue 已关闭,稳定性修复是社区的核心工作。从 UAF 到心跳配置,MQTT 的坑基本都被踩平了。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐