项目初始化
确认 Node.js 版本
本项目使用 Node.js v14.20.0 进行开发和测试,读者可用如下命令确认 Node.js 的版本
node --version
v14.20.0
使用 npm 安装 MQTT.js 客户端库
# 安装依赖
npm install mqtt --save
Node.js MQTT 使用
连接 MQTT 服务器
本文将使用 EMQ X 提供的 免费公共 MQTT 服务器,该服务基于 EMQ X 的 MQTT 物联网云平台 创建。服务器接入信息如下:
- Broker: http://broker.emqx.io(国内可以使用 http://broker-cn.emqx.io)
- TCP Port: 1883
- SSL/TLS Port: 8883
引入 MQTT.js 客户端库
注意:在 Node.js 环境中,导入依赖模块请使用 commonjs 规范
const mqtt = require('mqtt')
设置 MQTT Broker 的连接参数
//设置 MQTT Broker 连接地址,端口,客户端ID.
const host = 'broker.emqx.io' //连接地址
const port = '1883' //端口
//使用 JavaScript 中的生成随机数的函数来生成客户端ID.
const clientId = `mqtt_${Math.random().toString(16).slice(3)}`
编写 MQTT 连接函数
我们使用刚才设置的连接参数来进行连接,连接的 URL 通过上面定义的 host、port 端口来进行拼接。然后调用 mqtt 模块内置的 connect 函数,连接成功后返回一个 Client 实例。
const connectUrl = `mqtt://${host}:${port}`
const client = mqtt.connect(connectUrl, {
clientId,
clean: true,
connectTimeout: 4000,
username: 'emqx',
password: 'public',
reconnectPeriod: 1000,
})
订阅主题
//使用返回的 Client 实例的 on 方法来监听连接成功状态,
//并在连接成功后的回调函数中订阅 topic。
const topic = 'testtopic/#' // '/#'指testtopic下所有主题
client.on('connect', () => {
console.log('连接成功')
//此时我们连接成功后调用 Client 实例的 subscribe 方法订阅 testtopic/# 主题。
client.subscribe([topic], () => {
console.log(`订阅主题为: '${topic}'`)
})
})
监听接收消息
注意:回调函数中的 message 是 Buffer 类型,需要使用 toString 方法将其转化为字符串
//订阅主题成功后,我们再使用 on 方法来监听接收消息的方法,
//当接受到消息时,我们可以在该方法的回调函数中获取到 topic 和 message 消息。
client.on('message', (topic, payload) => {
var str = payload.toString();
console.log('监听接收消息:', topic,"(主题)",str ,"(消息)")
})
消息发布
注意:消息发布需要在 MQTT 连接成功以后,因此这里我们写到 Connect 成功的回调函数里
client.on('connect', () => {
//客户端(client)将发布一个消息到指定的主题(topic)。
// 'nodejs mqtt test' 这是消息的内容。
// { qos: 0, retain: false } 这是消息的属性,其中:
// qos:0 表示质量服务级别(QoS)为0,这意味着消息将被尽力传输,但不保证可靠性。
// retain:false 表示不保留消息,即发布后立即过期。
client.publish(topic, 'nodejs mqtt test', { qos: 0, retain: false }, (error) => {
if (error) { //检查发布操作是否发生错误。如果发生错误,将使用`console.error(error)`输出错误信息。
console.error(error)
}
})
})
完整代码
服务器连接、主题订阅、消息发布与接收的代码。
const mqtt = require('mqtt')
const host = 'broker.emqx.io'
const port = '1883'
const clientId = `mqtt_${Math.random().toString(16).slice(3)}`
const connectUrl = `mqtt://${host}:${port}`
const client = mqtt.connect(connectUrl, {
clientId,
clean: true,
connectTimeout: 4000,
username: 'emqx',
password: 'public',
reconnectPeriod: 1000,
})
const topic = '/nodejs/mqtt'
client.on('connect', () => {
console.log('Connected')
client.subscribe([topic], () => {
console.log(`Subscribe to topic '${topic}'`)
})
client.publish(topic, 'nodejs mqtt test', { qos: 0, retain: false }, (error) => {
if (error) {
console.error(error)
}
})
})
client.on('message', (topic, payload) => {
console.log('Received Message:', topic, payload.toString())
})