更新记录

1.0.0(2026-05-30) 下载此版本

初次提交


平台兼容性

uni-app x(4.75)

Chrome Safari Android iOS 鸿蒙 微信小程序
5.0

其他

多语言 暗黑模式 宽屏模式

laoqianjunzi-mqtt

laoqianjunzi-mqtt 是一个面向 uni-app x 的 MQTT 多端连接插件,提供统一的 MqttBridge 接口,用于在页面中完成连接、订阅、消息接收、消息发送和断开连接。

插件当前覆盖以下平台:

  • App-Android
  • App-iOS
  • App-Harmony
  • Web
  • 微信小程序

适合以下场景:

  • 设备控制与物联网状态同步
  • 即时消息、信令、轻量推送
  • 业务页面中的主题订阅与实时数据展示
  • 需要在多端复用同一套 MQTT 接入代码的 uni-app x 项目

功能概览

  • 统一的 MqttBridge 类接口
  • 支持 tcpsslwswss 四类连接协议
  • 支持连接状态监听与消息事件监听
  • 支持预设订阅主题 presetTopics
  • 支持遗嘱消息 lastWill
  • 支持发布 QoS、订阅 QoS、保留消息 retained
  • 支持自动重连 autoReconnect
  • 支持将接收消息按十六进制文本返回 receiveHexText
  • App 端支持 TLS 证书配置

版本要求

根据插件当前 package.json 配置,建议使用以下环境:

  • HBuilderX 5.07 或更高版本
  • uni-app x 4.75 或更高版本

平台支持矩阵

平台 MQTT 协议 证书配置 备注
App-Android tcp ssl ws wss 支持 原生基于 Paho Java
App-iOS tcp ssl ws wss 支持 原生基于 CocoaMQTT
App-Harmony tcp ssl ws wss 暂不生效 原生基于 @ohos/mqtt
Web ws wss 不支持 仅支持基于 WebSocket 的 MQTT
微信小程序 ws wss 不支持 仅支持基于 WebSocket 的 MQTT

注意事项:

  • Web微信小程序 端如果使用 tcpssl,会触发失败事件,错误码通常为 5304
  • 为了避免各平台对 ws/wss 默认路径处理不一致,建议始终显式传入 path,例如 /mqtt
  • 若目标平台本身要求域名白名单、WebSocket 合法域名或 TLS 证书配置,仍需同步完成平台侧配置

安装与导入

将插件放入项目 uni_modules 目录后,直接从插件根目录导入:

import { MqttBridge } from "@/uni_modules/laoqianjunzi-mqtt"

请注意:

  • 只从插件根目录导入,不要直接导入插件内部 utssdk 文件
  • 页面、组件和业务封装层建议都通过同一入口导入,避免跨平台类型识别不一致

快速开始

下面示例演示页面内最常见的接入方式:初始化实例、注册事件、建立连接、发送消息、离开页面时清理监听并断开连接。

<script setup lang="uts">
import {
    MqttBridge,
    MqttOpenOptions,
    MqttPublishPacket,
    MqttTopicRule
} from "@/uni_modules/laoqianjunzi-mqtt"

const bridge = new MqttBridge()
let readyToken = ""
let closedToken = ""
let failedToken = ""
let messageToken = ""

function bindBridgeEvents(): void {
    readyToken = bridge.on("ready", (payload) => {
        console.log("mqtt ready", payload.body)
    })

    closedToken = bridge.on("closed", (payload) => {
        console.log("mqtt closed", payload.body)
    })

    failedToken = bridge.on("failed", (payload) => {
        console.error("mqtt failed", payload.body)
    })

    messageToken = bridge.on("message", (payload) => {
        console.log("mqtt message", payload.channel, payload.body)
    })
}

function unbindBridgeEvents(): void {
    if (readyToken.length > 0) {
        bridge.off(readyToken)
    }
    if (closedToken.length > 0) {
        bridge.off(closedToken)
    }
    if (failedToken.length > 0) {
        bridge.off(failedToken)
    }
    if (messageToken.length > 0) {
        bridge.off(messageToken)
    }
    readyToken = ""
    closedToken = ""
    failedToken = ""
    messageToken = ""
}

function createTopics(): MqttTopicRule[] {
    return [{
        channel: "demo/device/status",
        qos: 1
    } as MqttTopicRule]
}

function connectBroker(): void {
    const options: MqttOpenOptions = {
        scheme: "wss",
        host: "broker.emqx.io",
        port: 8084,
        path: "/mqtt",
        clientId: "uniappx-demo-" + Date.now().toString(),
        username: null,
        password: null,
        cleanSession: true,
        autoReconnect: true,
        keepAliveSeconds: 60,
        timeoutSeconds: 15,
        receiveHexText: false,
        presetTopics: createTopics(),
        lastWill: null,
        certificate: null
    }

    try {
        bridge.connect(options)
    } catch (error) {
        console.error("mqtt connect error", error)
    }
}

function publishMessage(): void {
    const packet: MqttPublishPacket = {
        channel: "demo/device/status",
        body: "hello from uni-app x",
        qos: 1,
        retained: false
    }

    try {
        bridge.publish(packet, (ok: boolean) => {
            console.log("publish result", ok)
        })
    } catch (error) {
        console.error("mqtt publish error", error)
    }
}

onLoad(() => {
    bindBridgeEvents()
    connectBroker()
})

onUnload(() => {
    unbindBridgeEvents()
    try {
        bridge.disconnect()
    } catch (_) {
    }
})
</script>

如果你希望在连接成功后再手动订阅,也可以在 ready 事件中调用:

bridge.subscribe([
    {
        channel: "demo/device/status",
        qos: 1
    } as MqttTopicRule,
    {
        channel: "demo/device/command",
        qos: 0
    } as MqttTopicRule
])

取消订阅时传入主题字符串数组:

bridge.unsubscribe(["demo/device/status", "demo/device/command"])

对外类型

MqttBridgeScheme

连接协议枚举:

  • tcp
  • ssl
  • ws
  • wss

MqttBridgeState

连接状态枚举:

  • idle:已配置或初始状态,尚未发起连接
  • opening:连接建立中
  • ready:连接可用
  • closed:连接已关闭
  • failed:连接或操作失败

MqttBridgeEventName

事件名称枚举:

  • ready
  • closed
  • failed
  • message

MqttTopicRule

订阅主题对象:

字段 类型 必填 说明
channel string 主题名
qos number 订阅 QoS,建议填 012

MqttLastWill

遗嘱消息配置:

字段 类型 必填 说明
channel string 遗嘱主题
body string 遗嘱消息内容
qos number 遗嘱消息 QoS
retained boolean 是否保留

MqttCertificateProfile

TLS 证书配置:

字段 类型 必填 说明
allowInsecure boolean 是否允许不校验证书,仅建议调试环境使用
assetName string 证书资源文件名,建议使用 xxx.ext 形式
assetPassword string 证书口令,p12pfxbks 等场景需要

MqttOpenOptions

连接参数:

字段 类型 必填 说明
scheme MqttBridgeScheme 连接协议
host string 服务端域名或 IP,不含协议前缀
port number 端口
path string ws/wss 常用路径,推荐显式传入 /mqtt
clientId string MQTT 客户端标识
username string \| null 用户名
password string \| null 密码
cleanSession boolean 是否清理会话,建议显式传入
autoReconnect boolean 是否自动重连,建议显式传入
keepAliveSeconds number 心跳间隔,单位秒
timeoutSeconds number 连接超时,单位秒
receiveHexText boolean 是否将接收数据转换为十六进制文本
presetTopics MqttTopicRule[] \| null 建连成功后自动订阅的主题列表
lastWill MqttLastWill \| null 遗嘱消息
certificate MqttCertificateProfile \| null TLS 证书配置

MqttPublishPacket

发送消息参数:

字段 类型 必填 说明
channel string 发布主题
body string 消息内容
qos number 发布 QoS
retained boolean 是否保留

MqttEventPayload

事件回调数据:

字段 类型 说明
eventName MqttBridgeEventName 当前事件名
channel string \| null 主题名,非消息类事件通常为 null
body string 事件说明或消息体
ok boolean 当前事件是否成功

MqttBridge API

new MqttBridge()

创建 MQTT 客户端实例。

configure(options: MqttOpenOptions): void

仅保存连接配置,不立即发起连接。适合以下场景:

  • 页面先初始化配置,稍后由按钮触发连接
  • 需要多次读取或复用同一套连接参数

connect(options: MqttOpenOptions | null = null): void

建立连接。

  • 传入 options 时会先更新配置再连接
  • 传入 null 时会尝试使用上一次 configureconnect 时保存的配置
  • 建议始终监听 readyfailed 事件,不要只依赖同步 try/catch

subscribe(topics: MqttTopicRule[]): void

订阅一个或多个主题。

  • 连接未就绪时会失败
  • 空数组会失败
  • 多主题订阅时建议为每个主题显式声明 QoS

unsubscribe(channels: string[]): void

取消订阅。

  • 传入主题字符串数组
  • 空数组不会产生有效取消动作

publish(packet: MqttPublishPacket, listener?: (ok: boolean) => void): void

发送消息。

  • listener(true) 表示本次发送动作已成功提交到当前客户端实现
  • 这不是业务层“服务端已处理完成”的确认语义
  • 为了跨平台稳定性,建议 channelbody 都传入非空字符串

disconnect(): void

主动断开连接。

  • 页面退出、账号切换、Broker 变更时建议主动调用
  • 如果你为实例注册过事件,也建议同步 off(token) 清理

isConnected(): boolean

返回当前是否处于可用连接状态。

getState(): MqttBridgeState

返回当前连接状态。

on(eventName: MqttBridgeEventName, listener: MqttEventListener): string

注册事件监听,并返回一个事件令牌 token

推荐把返回值保存下来,页面销毁时用于解除绑定。

off(token: string): void

根据 on 返回的事件令牌移除监听。

事件说明

ready

连接成功后触发。

常见用途:

  • 更新页面连接状态
  • 手动执行补充订阅
  • 启动心跳、初始化业务同步逻辑

closed

连接关闭时触发。

常见场景:

  • 主动调用 disconnect()
  • 底层连接被关闭
  • 部分平台在连接中断后会先进入关闭状态

failed

连接、订阅、发送或取消订阅失败时触发。

建议处理方式:

  • 记录 payload.body 到页面日志
  • 对用户展示可读错误提示
  • 按业务场景决定是否重试或重新连接

message

收到 MQTT 消息时触发。

  • payload.channel 为消息主题
  • payload.body 为消息内容
  • receiveHexTexttrue 时,body 返回十六进制文本

TLS 与证书配置

当你使用 sslwss 时,可以通过 certificate 传入证书参数。

const options: MqttOpenOptions = {
    scheme: "ssl",
    host: "your-broker.example.com",
    port: 8883,
    path: null,
    clientId: "secure-client",
    username: null,
    password: null,
    cleanSession: true,
    autoReconnect: true,
    keepAliveSeconds: 60,
    timeoutSeconds: 15,
    receiveHexText: false,
    presetTopics: null,
    lastWill: null,
    certificate: {
        allowInsecure: false,
        assetName: "mqtt-client.p12",
        assetPassword: "123456"
    }
}

当前实现层面的证书能力如下:

  • Android 支持:.cer.crt.pem.der.p12.pfx.bks
  • iOS 支持:.cer.crt.der.pem.p12
  • Harmony、Web、微信小程序当前不会实际消费 certificate 配置

建议:

  • assetName 使用简单文件名加扩展名,不要写绝对路径
  • allowInsecure 只用于开发调试,不建议上线环境开启
  • 生产环境优先使用正式 CA 或明确可控的自签名证书

错误码

插件当前定义了以下错误码:

错误码 含义
5301 缺少 hostclientId
5302 协议、端口或目标地址无效
5303 客户端尚未准备完成,通常是未连接或未配置就发起操作
5304 当前平台不支持该传输方式
5305 订阅参数为空或订阅主题无效
5306 发布参数无效

常见排查方向:

  • 5301:检查 hostclientId 是否为空字符串
  • 5302:检查 schemeportpath、Broker 地址是否正确
  • 5303:检查是否先连接成功再订阅或发送
  • 5304:检查是否在 Web 或微信小程序上误用了 tcp/ssl
  • 5305:检查主题数组是否为空,主题名是否为空字符串
  • 5306:检查发布主题和消息体是否满足当前平台要求

跨平台使用建议

为了让同一套业务代码在多端更稳定,建议遵循以下规则:

  • ws/wss 一律显式传 path,不要依赖平台默认值
  • cleanSessionautoReconnectkeepAliveSecondstimeoutSeconds 一律显式传值,不要依赖不同平台的默认行为
  • 事件监听统一保留 token,页面卸载时主动 off(token)
  • 页面卸载时主动 disconnect(),避免后台残留连接
  • 如果业务依赖二进制内容,receiveHexText 返回值更适合展示或日志记录;需要严格字节协议解析时,建议在业务层自行做格式统一
  • 发送消息时尽量避免空主题、空消息体,提升跨平台一致性

App 端注意事项

  • Android 项目需要具备网络访问能力
  • 若使用 TLS 证书,请确认资源文件已被正确打入应用包中
  • iOS 若使用自签名或私有证书链,请先在测试环境验证握手行为再上线

微信小程序与 Web 注意事项

  • 只支持 wswss
  • 更推荐使用 wss
  • path 建议明确写出,例如 /mqtt
  • 平台侧若有域名校验、证书校验或安全策略限制,需要同步完成配置

示例页面

插件内已经附带演示页面,可直接参考:

  • uni_modules/laoqianjunzi-mqtt/pages/index.uvue

该页面展示了:

  • 协议切换
  • 建立连接
  • 自动订阅与手动订阅
  • 消息发送
  • 取消订阅
  • 实时日志输出

推荐接入方式

在实际项目中,推荐把 MqttBridge 包装成你自己的业务服务层,然后在页面中只处理:

  • 当前页面是否需要订阅
  • 当前页面关注哪些主题
  • 何时进入连接
  • 何时离开连接
  • 收到消息后如何映射到业务状态

这样更方便处理以下问题:

  • 多页面复用连接
  • 统一重连策略
  • 统一错误提示
  • 统一日志记录
  • 不同主题分发到不同业务模块

更新说明

1.0.0

  • 首个公开版本
  • 提供 uni-app x 多端统一 MQTT 接入能力

隐私、权限声明

1. 本插件需要申请的系统权限列表:

<uses-permission android:name="android.permission.INTERNET"/>

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

仅在本地与 MQTT 服务端建立网络连接,不内置数据采集逻辑

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。