本文详细介绍 mqtt.js 在 JavaScript 环境中的使用方法,涵盖 CDN 与 npm 两种安装方式。重点解析连接配置、消息发布与订阅、客户端生命周期管理等核心 API,并针对 4.2.x 版本报错提供解决方案及 EMQX 公共服务器测试示例。
本文旨在介绍 mqtt.js 库的具体使用方式。
一、说明
- 本文使用的版本是
4.1.x,未采用最新版的原因是4.2.x及以上版本会出现报错,具体错误信息可参考文末说明。 - 使用的
4.1.x版本下载地址为:https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js - 若遇到
无法连接/错误提示 WebSocket connection to ……的问题,请参阅我的另一篇文章,其中记录了多次遇到的连接问题及解决方法,点击查看。
二、安装
CDN 安装方式如下:
<script src="https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js"></script>
<script>
// 会在全局初始化一个 mqtt 变量,直接使用就可以
console.log(mqtt)
</script>npm 安装方式如下:
npm install mqtt --savenpm 安装后,在页面中直接 import 即可使用:
// 页面使用,直接 import 就可以
import mqtt from 'mqtt';三、使用
以下为常用连接方式及详细配置说明。
// 连接地址,有很多连接失败都是因为地址没写对
const connectUrl = `ws://XXXX/mqtt/ws`;
// 客户端ID
const clientId = `mqtt_${Math.random().toString(16).slice(3)}`;
// 连接设置
let options = {
clean: true, // 保留会话
connectTimeout: 4000, // 超时时间
reconnectPeriod: 1000, // 重连时间间隔
// 认证信息
clientId,
username: 'zhongketianji',
password: 'zhongketianji123',
}
// 需要订阅的主题
const topic = '/mqtt_backend/format_tracking/Uibox.car190';
const topic1 = '/mqtt_backend/format_tracking/Uibox.car191';
// 创建客户端
var client = mqtt.connect(connectUrl, options);
// 成功连接后触发的回调
client.on('connect', () => {
console.log('已经连接成功');
// 订阅主题,这里可以订阅多个主题
client.subscribe([topic, topic1], () => {
console.log(`订阅了主题 ${[topic, topic1].join('和')}`)
})
});
// 当客户端收到一个发布过来的消息时触发回调
/**
* topic:收到的报文的topic
* message:收到的数据包的负载playload
* packet:MQTT 报文信息,其中包含 QoS、retain 等信息
*/
client.on('message', function (topic, message, packet) {
// 这里有可能拿到的数据格式是Uint8Array格式,可以直接用toString转成字符串
// let data = JSON.parse(message.toString());
console.log("获取到的数据:", message)
console.log("数据对应订阅主题:", topic)
console.log("获取到的数据包:", packet)
});
// 关闭客户端(断开连接)
client.end();
// 发送信息给 topic(主题)
client.publish(topic, '这是给topic发送的信息');options 连接设置(常用参数)
| 属性 | 说明 |
|---|---|
| keepalive | 单位为秒,数值类型,默认为 60 秒,设置为 0 时禁止。用于解决半连接问题,在该时间内是否接收两次传输 |
| clientId | 默认为 ‘mqttjs_’ + Math.random().toString(16).substr(2, 8),可自定义修改,字符串类型 |
| protocolVersion | MQTT 协议版本号,默认为 4(v3.1.1)可以修改为 3(v3.1)和 5(v5.0) |
| clean | 是否清除会话,默认为 true。当设置为 true 时,断开连接后将清除会话,订阅过的 Topic 也将失效。当设置为 false 时,离线状态下也能收到 QoS 为 1 和 2 的消息 |
| reconnectPeriod | 重连间隔时间,单位为毫秒,默认为 1000 毫秒,注意:当设置为 0 以后将取消自动重连 |
| connectTimeout | 连接超时时长,收到 CONNACK 前的等待时间,单位为毫秒,默认 30000 毫秒 |
| username | 认证用户名,如果 Broker 要求用户名认证的话,请设置该值 |
| password | 认证密码,如果 Broker 要求密码认证的话,请设置该值 |
| will | 遗嘱消息,一个可配置的对象值,当客户端非正常断开连接时,Broker 就会向遗嘱 Topic 里面发布一条消息。 |
will 遗嘱消息格式如下:
will: {
topic: 'WillMsg', // 发布消息的主题
payload: 'Connection Closed abnormally!', // 要发布的消息
qos: 0, // 消息等级
retain: false // 保留消息标识
},Client 监听事件(on 方法)
// 成功连接后触发的回调
client.on('connect', () => {
console.log('已经连接成功');
});
// 当客户端收到一个发布过来的消息时触发回调
/**
* topic:收到的数据包的topic
* message:收到的数据包的负载playload
* packet:MQTT 报文信息,其中包含 QoS、retain 等信息
*/
client.on('message', function (topic, message, packet) {
// 这里有可能拿到的数据格式是Uint8Array格式,可以直接用toString转成字符串
// let data = JSON.parse(message.toString());
console.log("获取到的数据:", data_190)
console.log("数据对应订阅主题:", topic)
console.log("获取到的数据包:", packet)
});
// 当重新连接启动触发回调
client.on('reconnect', () => {
console.log("正在重新连接")
});
// 连接断开后触发的回调
client.on("close",function () {
console.log("已断开连接")
});
// 在收到 Broker(消息服务器) 发送过来的断开连接的报文时触发的回调,参数 packet 即为断开连接时接收到的报文。MQTT 5.0特性
client.on("disconnect",function (packet) {
console.log("从broker接收到断开连接的报文:"+packet);
});
// 客户端脱机下线触发回调
client.on("offline",function () {
console.log("您已断开连接,请检查网络")
});
// 当客户端无法成功连接时或发生解析错误时触发的回调,参数 error 为错误信息
client.on("error",(error) =>{
console.log("客户端出现错误:", error);
});
//当客户端发送任何数据包时发出。这包括publish()以及MQTT用于管理订阅和连接的包
client.on("packetsend",(packet)=>{
console.log("客户端已发出报文", packet);
});
//当客户端接收到任何报文时发出。这包括来自订阅主题的信息包以及MQTT用于管理订阅和连接的信息
client.on("packetreceive",(packet)=>{
// 会在 client.on('message', function (topic, message, packet) {}); 之前触发
console.log("客户端接收报文", packet);
});
Client 其他常用方法(除 on 方法外)
向指定 topic(主题)发布消息
Client.publish(topic, message, [options], [callback])topic:要发送的主题(字符串类型) message:该主题下的消息内容,可以是字符串或
Buffer类型 options:可选参数,用于配置发布消息时的QoS和Retain等值 callback:发布消息后的回调函数,参数为error,仅在发布失败时存在
// 向 test 主题发送一条 QoS 为 0 的消息
client.publish('test', '这是一条信息', { qos: 0, retain: false }, function (error) {
if (error) {
console.log(error)
} else {
console.log('Published')
}
})订阅一个或多个 topic(主题)的方法(连接成功后需订阅以接收消息)
Client.subscribe(topic/topic array/topic object, [options], [callback])topic:可传入单个字符串、字符串数组或
topic对象,例如:{‘test1’: {qos: 0}, ‘test2’: {qos: 1}} options:可选参数,用于配置订阅Topic时的信息,主要设置订阅Topic的QoS等级 callback:订阅Topic后的回调函数,参数为error和granted。若订阅失败,error参数存在;granted是一个包含 {topic, qos} 的数组,其中topic表示被订阅的主题,qos表示被授予的Topic的QoS等级
// 订阅一个名为 test 且 QoS 为 0 的 Topic
client.subscribe('test', { qos: 0 }, function (error, granted) {
if (error) {
console.log("订阅失败:", error)
} else {
console.log("已订阅:", granted[0].topic)
}
})取消订阅单个或多个 topic(主题)
Client.unsubscribe(topic/topic array, [options], [callback])topic:可传入单个字符串或字符串数组 options:可选参数,用于配置取消订阅时的信息 callback:取消订阅时的回调函数,参数为
error。若取消订阅失败,error参数存在
// 取消订阅名为 test 的 Topic
client.unsubscribe('test', function (error) {
if (error) {
console.log(error)
} else {
console.log('已取消订阅')
}
})关闭客户端
Client.end([force], [options], [callback])force:设置为
true时将立即关闭客户端,无需等待断开连接的消息被接收。该参数可选,默认为false。注意:当该值为true时,Broker无法接收到disconnect报文 options:可选参数,用于配置关闭客户端时的信息,主要可配置reasonCode及断开连接时的Reason Codecallback:客户端关闭时的回调函数
client.end();四、测试
EMQX 提供的免费公共 MQTT 服务器,基于 EMQX 的 MQTT 物联网云平台创建。服务器接入信息如下:
Broker: broker.emqx.io TCP Port: 1883 Websocket Port: 8083
const connectUrl = `ws://broker.emqx.io:8083/mqtt`;
client = mqtt.connect(connectUrl, {
clean: true,
connectTimeout: 4000,
reconnectPeriod: 1000,
clientId: 'emqx_test',
username: 'emqx_test',
password: 'emqx_test'
})
// 需要订阅的主题
const topic = 'test';
//成功连接后触发的回调
client.on('connect', () => {
console.log('已经连接成功');
// 这里可以订阅多个主题
client.subscribe([topic], () => {
console.log(`订阅了主题 ${topic}`)
})
});
// 当客户端收到一个发布过来的消息时触发回调
client.on('message', function (message) {
// 这里有可能拿到的数据格式是Uint8Array格式,所以可以直接用toString转成字符串
// let data = JSON.parse(message.toString());
console.log("返回的数据:", message)
});
// 连接断开后触发的回调
client.on("close", function () {
console.log("已断开连接")
});
五、测试结果

PS:关于 mqtt.js 报错 n.createConnection is not a function

原因:此为版本兼容问题,4.2.x 及以上版本(目前最新版仍存在此问题,后续可能改进)
解决方案:使用较低版本,例如 4.1.x 即可。(CDN 地址见前文)
此处展示了连接成功后输出的 client 对象信息。

VUE 环境下的解决方案:
据网络资料,在 Vue 项目中安装时,除了修改版本外,还需将 package.json 中版本号前的 ^ 符号去掉。由于未使用 Vue 进行测试,建议读者自行尝试(此处引用了其他博客的截图)。

可选择版本的地址:https://www.bootcdn.cn/mqtt/
本文使用的具体地址:https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js
至此,关于 JS 连接 MQTT 的使用方法介绍完毕。如需了解更多 MQTT 使用相关内容,请搜索本站历史文章或继续浏览后续文章。感谢大家的支持!