Skip to main content

MQTT 插件

@capacitor-rydeen/mqtt 为 Android、iOS、Web、Electron 提供统一的 MQTT 客户端能力:连接、订阅、发布、心跳与网络质量监控,并通过事件驱动(addListener)向应用层推送消息与状态变化。

插件设计目标:

  • 在弱网/移动网络环境中尽量保持「不断连」,自动处理重连;
  • 对外暴露统一的 TypeScript API 和事件模型,隐藏各平台底层差异;
  • 为门店终端、收银机、一体机等场景提供稳定的消息通道。

支持平台:Android / iOS / Web / Electron,各平台能力差异见下文「平台能力矩阵」。

设计思想​

  • 事件驱动:所有消息、连接状态、心跳、订阅结果、网络质量等都通过事件推送到 JS 层,前端只需订阅对应事件即可。
  • 弱网不断连:通过 keepAliveInterval、reconnectInterval、maxReconnectAttempts、heartbeatEnabled、monitorEnabled 等配置,在断网/恢复、App 前后台切换等情况下自动恢复连接。
  • 网络路径切换:通过 NetworkPathType(PUBLIC / VPC)与 vpcHost/vpcPort,在公网与 VPC 之间平滑切换。
  • 平台对齐:Android/iOS 使用原生 MQTT 客户端(弱网优化、心跳、网络质量);Web/Electron 使用 mqtt 包的 WebSocket 实现,并尽量对齐事件与心跳格式。

安装与集成​

npm install @capacitor-rydeen/mqtt
npx cap sync

Web / Electron 需要安装对等依赖:

npm install mqtt

在应用中导入:

import { Mqtt } from '@capacitor-rydeen/mqtt'

平台能力矩阵​

能力AndroidiOSWebElectron
方法
connect✅✅✅✅
reconnect✅✅✅✅
isConnected✅✅✅✅
disconnect✅✅✅✅
subscribe✅✅✅✅
unsubscribe✅✅✅✅
updateConfig✅✅✅✅
switchServer✅✅✅✅
publish✅✅✅✅
事件
mqttMessage✅✅✅✅
mqttConnectionState✅✅✅✅
mqttSubscriptionResult✅✅✅✅
mqttHeartbeat✅✅✅✅
mqttSignalStrength✅❌❌❌
mqttNetworkQuality✅✅❌❌
  • Android:原生实现(依赖 rydeen-mqtt-android),TCP/TLS 直连,支持全部 6 类事件(消息、连接状态、心跳、信号强度、网络质量、订阅结果)。
  • iOS:原生实现(见 ios/DESIGN.md),TCP/TLS 直连;实现消息、连接状态、心跳、订阅结果、网络质量。
    • 信号强度:iOS 无公开 API 获取实时 RSSI/dBm,暂不实现。
    • 网络质量:在 monitorEnabled 为 true 时,按 monitorCheckInterval 对 Broker host:port 做 TCP 建连测时与丢包统计,通过 mqttNetworkQuality 上报。
  • Web:基于 npm 包 mqtt,使用 WebSocket(ws/wss)连接 /mqtt 端点;实现消息、连接状态、订阅结果、心跳事件:
    • heartbeatEnabled 为 true 时,按 keepAliveInterval 向 $heartbeat/{clientId} 发心跳并触发 mqttHeartbeat;
    • 无系统级信号强度/网络质量,mqttSignalStrength / mqttNetworkQuality 不可用。
  • Electron:与 Web 共用同一套 MqttWeb 实现,能力与 Web 一致。

快速开始​

import { Mqtt } from '@capacitor-rydeen/mqtt'

// 1. 建立连接
await Mqtt.connect({
server: {
host: 'your-broker.com',
port: 8883,
username: 'user',
password: 'pass',
clientId: 'my-client-id',
networkPath: 'PUBLIC',
vpcHost: 'vpc-broker.com',
vpcPort: 8883
},
keepAliveInterval: 60,
reconnectInterval: 5000,
heartbeatEnabled: true,
monitorEnabled: true,
autoReconnect: true
})

// 2. 监听连接状态
Mqtt.addListener('mqttConnectionState', (e) => {
console.log('[MQTT] state =', e.state, e.stateDesc, 'network:', e.networkType)
})

// 3. 监听消息
Mqtt.addListener('mqttMessage', (msg) => {
console.log('[MQTT] message', msg.topic, msg.payload)
})

// 4. 订阅与发布
await Mqtt.subscribe({ topic: 'device/+/status' })

await Mqtt.publish({
topic: 'device/123/cmd',
payload: JSON.stringify({ action: 'reboot' }),
qos: 1,
retained: false,
messageId: '',
properties: new Map()
})

实战示例:门店终端在线状态与远程指令​

场景:门店一体机通过 MQTT 上报自身在线状态、网络质量,并接收后台下发的远程指令(如重启、更新配置)。

Topic 约定​

  • 状态上报:status/{clientId}
  • 心跳:$heartbeat/{clientId}(插件内部已实现)
  • 网络质量:通过 mqttNetworkQuality 事件上报;
  • 远程指令:cmd/{clientId}/#

共享订阅 Topic 规则(Shared Subscription)​

在需要做「多实例均衡消费」时,可以使用 MQTT 共享订阅,标准写法为:

  • 协议版本要求:

    • 共享订阅是 MQTT 5.0 标准中新增的特性,大部分 Broker 需要显式开启或仅在 MQTT 5.0 连接下可用;
    • 使用前请确认 Broker 已支持并开启共享订阅能力。
  • 基本语法:$share/{groupId}/{topicFilter}

    • groupId:共享组 ID,用于把多个客户端划入同一消费组,例如 store-terminal;
    • topicFilter:常规的 Topic Filter,例如 cmd/{clientId}/#、status/+/online 等。
  • 组内均衡消费:

    • 同一 groupId + topicFilter 下,只会有 一个 在线客户端实际收到某条消息,用于做负载均衡;
    • 需要多实例同时收到消息时,请使用普通订阅(非 $share/ 前缀)。
  • Topic Filter 规则:

    • topicFilter 的写法与普通订阅完全一致,支持 +、# 通配符;
    • 禁止 在 groupId 中使用 /、+、# 等分隔符和通配符,推荐只用字母、数字与中划线/下划线。
  • 订阅示例:

    • 单个客户端订阅:cmd/{clientId}/#(所有实例都能收到)
    • 共享订阅(同组均衡):$share/store-terminal/cmd/{clientId}/#
  • 与插件配合使用:

    • 在 Mqtt.subscribe 的 topic 字段中,直接传入以上 $share/... 形式即可;
    • 建议同一业务类型统一约定 groupId,避免不同应用意外进入同一共享组。
  • 典型使用场景:

    • 共享订阅通常用于 服务端 / 后台消费端(如订单处理集群、推送服务集群),以实现多实例之间的消息负载均衡;
    • 一般业务侧前端/客户端不需要使用共享订阅,但在 门店有多台 POS 机 的场景中,为避免单点故障,也可以考虑让多台 POS 机加入同一共享组来「接单」,只要有一台在线即可消费到该订单。

代码示例(简化版)​

import { Mqtt } from '@capacitor-rydeen/mqtt'

async function setupMqtt(clientId: string) {
await Mqtt.connect({
server: {
host: 'broker.rydeen.com',
port: 8883,
username: clientId,
password: '***',
clientId,
networkPath: 'PUBLIC',
vpcHost: 'mqtt-vpc.rydeen.com',
vpcPort: 8883
},
keepAliveInterval: 60,
reconnectInterval: 5000,
heartbeatEnabled: true,
monitorEnabled: true,
monitorCheckInterval: 30,
autoReconnect: true
})

// 1. 订阅远程指令
await Mqtt.subscribe({ topic: `cmd/${clientId}/#` })

// 2. 监听指令消息
Mqtt.addListener('mqttMessage', (msg) => {
if (!msg.topic.startsWith(`cmd/${clientId}/`)) return
const payload = JSON.parse(msg.payload || '{}')
switch (payload.action) {
case 'reboot':
// 触发应用重启或提示用户
break
case 'update-config':
// 更新本地配置后持久化到 storage/preferences
break
}
})

// 3. 监听心跳与网络质量
Mqtt.addListener('mqttHeartbeat', (hb) => {
console.log('[MQTT] heartbeat', hb.clientId, hb.status, hb.timestamp)
})

Mqtt.addListener('mqttNetworkQuality', (q) => {
console.log('[MQTT] quality', q.pingLatency, 'ms', q.packetLossDesc)
// 可上报到 logger 或展示在 UI
})
}

在实际项目中,推荐将上述逻辑封装为 MqttService,由应用启动流程统一初始化,并通过状态管理(如 Angular Service / RxJS / Signal)向组件层暴露简化后的状态。

API 与类型参考​

本节根据 src/definitions.ts 展开所有方法、事件与类型,便于仅靠文档就能开发。

方法列表​

方法签名说明
connectconnect(config: MqttConfig): Promise<void>建立连接。
reconnectreconnect(): Promise<void>使用最近一次配置重连;若用户主动 disconnect 则不再自动重连。
isConnectedisConnected(): Promise<MqttConnectionResult>返回当前是否已连接。
disconnectdisconnect(): Promise<void>主动断开连接,标记为用户断开。
subscribesubscribe(config: MqttSubscribeConfig): Promise<void>订阅主题。
unsubscribeunsubscribe(config: MqttSubscribeConfig): Promise<void>取消订阅。
updateConfigupdateConfig(config: MqttConfig): Promise<void>更新配置,不主动断开重连。
switchServerswitchServer(config: MqttSwitchServerConfig): Promise<void>按 networkPath 切换到 PUBLIC/VPC 并重连。
publishpublish(config: MqttPublishConfig): Promise<void>发布消息。

事件(addListener)​

事件名回调参数类型说明
mqttMessageMqttMessage收到订阅主题的消息。
mqttConnectionStateMqttConnection连接状态变化(connected / disconnected / reconnecting / error 等)。
mqttSubscriptionResultMqttSubscriptionResult订阅/取消订阅结果。
mqttHeartbeatMqttHeartbeat心跳上报(clientId、status、timestamp)。
mqttSignalStrengthMqttSignalStrength信号强度(仅 Android)。
mqttNetworkQualityMqttNetworkQuality网络质量(Android、iOS)。

主要类型摘要​

完整字段与默认值请参考源码中的 src/definitions.ts,此处列出关键字段与含义。

  • MqttConfig:连接与行为配置

    • server: MqttServer:MQTT 服务端配置;
    • sessionExpiryInterval?: number:会话过期时间;
    • keepAliveInterval?: number:保活/心跳间隔(秒);
    • reconnectInterval?: number:重连间隔(毫秒);
    • maxReconnectAttempts?: number:最大重连次数;
    • heartbeatEnabled?: boolean:是否启用心跳;
    • monitorEnabled?: boolean:是否启用网络监控;
    • monitorCheckInterval?: number:网络质量检测间隔(秒);
    • autoReconnect?: boolean:是否自动重连。
  • MqttServer:服务端与网络路径

    • host: string:主机;port: number:端口;
    • username: string / password: string:鉴权;
    • clientId: string:客户端 ID;
    • groupId?: string:分组 ID;
    • networkPath?: 'PUBLIC' | 'VPC':网络路径;
    • vpcHost?: string / vpcPort?: number:VPC 主机与端口。
  • MqttPublishConfig:发布参数

    • topic: string、payload: string、qos: number、retained: boolean、messageId: string、properties: Map<string,string>。
  • 事件 payload:

    • MqttMessage:topic、messageId、timestamp、retained、qos、payload、properties;
    • MqttConnection:state、stateDesc、networkType;
    • MqttHeartbeat:clientId、status、timestamp;
    • MqttSubscriptionResult:topic、timestamp、action、success、messageId;
    • MqttSignalStrength:networkType、signalStrength、signalStrengthDesc;
    • MqttNetworkQuality:pingLatency、pingLatencyDesc、packetLoss、packetLossDesc。

在实际使用中,建议为以上事件定义统一的封装层(如 MqttService),对上层屏蔽 topic 细节、错误重试与平台差异。