MQTT.js 入門使用教程
簡介
MQTT.js 是一個(gè)開源的 MQTT 協(xié)議的客戶端庫,使用 JavaScript 編寫,主要用于 Node.js 和 瀏覽器環(huán)境中。是目前 JavaScript 生態(tài)中使用最為廣泛的 MQTT 客戶端庫。
MQTT 是一種基于發(fā)布/訂閱模式的輕量級物聯(lián)網(wǎng)消息傳輸協(xié)議,可以用極少的代碼和帶寬為聯(lián)網(wǎng)設(shè)備提供實(shí)時(shí)可靠的消息服務(wù),它廣泛應(yīng)用于物聯(lián)網(wǎng)、移動(dòng)互聯(lián)網(wǎng)、智能硬件、車聯(lián)網(wǎng)、電力能源等行業(yè)。
由于 JavaScript 單線程特性,MQTT.js 是全異步 MQTT 客戶端,MQTT.js 支持 MQTT/TCP、MQTT/TLS、MQTT/WebSocket,在不同運(yùn)行環(huán)境支持的度如下:
- 瀏覽器環(huán)境:MQTT over WebSocket(包括微信小程序、支付寶小程序等定制瀏覽器環(huán)境)
- Node.js 環(huán)境:MQTT、MQTT over WebSocket
注意:不同環(huán)境里除了少部分連接參數(shù)不同,其他 API 均是相同的。且在 MQTT.js v3.0.0 及以上版本后,已經(jīng)完整支持到 MQTT 5.0。
安裝
使用 npm 或 yarn 安裝
npm install mqtt --save # 或使用 yarn yarn add mqtt
注意:如果您的 Node 環(huán)境是 v12 或 v14 及以上版本,請使用 MQTT.js 4.0.0 及以上版本
使用 CDN 安裝
在瀏覽器環(huán)境中,我們還可以使用 CDN 的方式引入 MQTT.js。MQTT.js 的 bundle 包通過 http://unpkg.com 管理,我們可以直接添加 unpkg.com/mqtt/dist/mqtt.min.js 來進(jìn)行使用。
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <script> // 將在全局初始化一個(gè) mqtt 變量 console.log(mqtt) </script>
全局安裝
除了上述的安裝方式外,MQTT.js 還提供了全局安裝的方式,使用命令行工具來完成 MQTT 的連接、發(fā)布和訂閱等。
npm install mqtt -g
我們會(huì)在下文中的一些使用教程中詳細(xì)描述如何使用 MQTT.js 的命令行工具。
使用
本文將使用 EMQX Cloud 提供的 免費(fèi)公共 MQTT 服務(wù)器 作為本次測試的 MQTT 服務(wù)器地址,服務(wù)器接入信息如下:
- Broker: broker.emqx.io
- TCP Port: 1883
- SSL/TLS Port: 8883
更多詳情請?jiān)L問 EMQX Cloud 官網(wǎng),或查看 EMQX Cloud 文檔。
簡單例子
我們簡單編寫一段代碼實(shí)現(xiàn)連接到 EMQX Cloud 并完成訂閱主題、收發(fā)消息的簡單例子。因?yàn)樵跒g覽器環(huán)境中僅支持使用 WebSocket 連接,所以我們將使用在瀏覽器環(huán)境和 Node.js 環(huán)境兩種不同的連接參數(shù)來完成連接。不過除連接地址外,其它參數(shù)均是相同的,因此讀者可根據(jù)自己的實(shí)際情況選擇使用。
const mqtt = require('mqtt') /*** * 瀏覽器環(huán)境 * 使用協(xié)議為 ws 和 wss 的 MQTT over WebSocket 連接 * EMQX 的 ws 連接默認(rèn)端口為 8083,wss 為 8084 * 注意需要在連接地址后加上一個(gè) path, 例如 /mqtt */ const url = 'ws://broker.emqx.io:8083/mqtt' /*** * Node.js 環(huán)境 * 使用協(xié)議為 mqtt 和 mqtts 的 MQTT over TCP 連接 * EMQX 的 mqtt 連接默認(rèn)端口為 1883,mqtts 為 8084 */ // const url = 'mqtt://broker.emqx.io:1883' // 創(chuàng)建客戶端實(shí)例 const options = { // Clean session clean: true, connectTimeout: 4000, // 認(rèn)證信息 clientId: 'emqx_test', username: 'emqx_test', password: 'emqx_test', } const client = mqtt.connect(url, options) client.on('connect', function () { console.log('Connected') // 訂閱主題 client.subscribe('test', function (err) { if (!err) { // 發(fā)布消息 client.publish('test', 'Hello mqtt') } }) }) // 接收消息 client.on('message', function (topic, message) { // message is Buffer console.log(message.toString()) client.end() })
命令行
在全局安裝完 MQTT.js 后,我們同樣可以使用命令行工具來完成主題訂閱消息發(fā)布接收的動(dòng)作。
示例連接到 broker.emqx.io
并訂閱 testtopic/#
主題:
mqtt sub -t 'testtopic/#' -h 'broker.emqx.io' -v
示例連接到 broker.emqx.io
并向 testtopic/hello
主題發(fā)送消息
mqtt pub -t 'testtopic/hello' -h 'broker.emqx.io' -m 'from MQTT.js'
如需使用功能更加全面的 MQTT 命令行工具,可參考使用 MQTT X CLI。
API 介紹
mqtt.connect([url], options)
連接到指定的 MQTT Broker 的函數(shù),并始終返回一個(gè) Client 對象。第一個(gè)參數(shù)傳入一個(gè) URL 值,URL 可以是以下協(xié)議:mqtt
, mqtts
, tcp
, tls
, ws
, wss
。URL 也可以是一個(gè)由 URL.parse() 返回的對象。然后再傳入一個(gè) Options 對象,用于配置 MQTT 連接時(shí)的選項(xiàng)。當(dāng)使用 WebSocket 連接時(shí)需要注意地址后是否需要加上一個(gè) path,例如 /mqtt
。
下面列舉一些常用的 Options 對象中的屬性值:
Options
keepalive
: 單位為秒
,數(shù)值類型,默認(rèn)為 60 秒,設(shè)置為 0 時(shí)禁止clientId
: 默認(rèn)為'mqttjs_' + Math.random().toString(16).substr(2, 8)
,可以支持自定義修改的字符串protocolVersion
: MQTT 協(xié)議版本號,默認(rèn)為 4(v3.1.1)可以修改為 3(v3.1)和 5(v5.0)clean
: 默認(rèn)為true
,是否清除會(huì)話。當(dāng)設(shè)置為true
時(shí),斷開連接后將清除會(huì)話,訂閱過的 Topics 也將失效。當(dāng)設(shè)置為false
時(shí),離線狀態(tài)下也能收到 QoS 為 1 和 2 的消息reconnectPeriod
: 重連間隔時(shí)間,單位為毫秒,默認(rèn)為 1000 毫秒,注意:當(dāng)設(shè)置為 0 以后將取消自動(dòng)重連connectTimeout
: 連接超時(shí)時(shí)長,收到 CONNACK 前的等待時(shí)間,單位為毫秒,默認(rèn) 30000 毫秒username
: 認(rèn)證用戶名,如果 Broker 要求用戶名認(rèn)證的話,請?jiān)O(shè)置該值password
: 認(rèn)證密碼,如果 Broker 要求密碼認(rèn)證的話,請?jiān)O(shè)置該值will
: 遺囑消息,一個(gè)可配置的對象值,當(dāng)客戶端非正常斷開連接時(shí),Broker 就會(huì)向遺囑 Topic 里面發(fā)布一條消息,格式為:topic
: 遺囑發(fā)送的 Topicpayload
: 遺囑發(fā)布的消息QoS
: 遺囑發(fā)送的 QoS 值retain
: 遺囑發(fā)布的消息的 retain 標(biāo)志
properties
: MQTT 5.0 新增,可配置的對象的屬性值,詳情請參考:https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
如果需要配置 SSL/TLS 連接,Option 對象會(huì)被傳遞給
tls.connect()
,因此可以在 option 中配置以下屬性rejectUnauthorized
: 是否驗(yàn)證服務(wù)端證書鏈和地址名稱,設(shè)置為 false 時(shí)將跳過驗(yàn)證,會(huì)暴露在中間人的攻擊之下,所以不建議在生產(chǎn)環(huán)境中使用這種配置,當(dāng)設(shè)置為 true 時(shí),將開啟強(qiáng)認(rèn)證模式,且如果是自簽名證書,請?jiān)谧C書配置時(shí)設(shè)置 Alt name。ca
: 只有在服務(wù)器使用自簽名證書時(shí)才有必要,自簽名證書中生成的 CA 文件cert
: 只有當(dāng)服務(wù)器需要客戶證書認(rèn)證時(shí)才有必要(雙向認(rèn)證),客戶端證書key
: 只有當(dāng)服務(wù)器需要客戶證書認(rèn)證時(shí)才有必要(雙向認(rèn)證),客戶端密鑰
Client 事件
當(dāng)連接成功后,返回的 Client 對象可通過 on 方法監(jiān)聽多個(gè)事件,業(yè)務(wù)邏輯可在監(jiān)聽的回調(diào)函數(shù)中完成。以下列舉一些常用的事件:
connect
當(dāng)連接成功時(shí)觸發(fā),參數(shù)為 connack
client.on('connect', function (connack) { console.log('Connected') })
reconnect
當(dāng)斷開連接后,經(jīng)過重連間隔時(shí)間重新自動(dòng)連接到 Broker 時(shí)觸發(fā)
client.on('reconnect', function () { console.log('Reconnecting...') })
close
在斷開連接以后觸發(fā)
client.on('close', function () { console.log('Disconnected') })
disconnect
在收到 Broker 發(fā)送過來的斷開連接的報(bào)文時(shí)觸發(fā),參數(shù) packet 即為斷開連接時(shí)接收到的報(bào)文,MQTT 5.0 中的功能
client.on('disconnect', function (packet) { console.log(packet) })
offline
當(dāng)客戶端下線時(shí)觸發(fā)
client.on('offline', function () { console.log('offline') })
error
當(dāng)客戶端無法成功連接時(shí)或發(fā)生解析錯(cuò)誤時(shí)觸發(fā),參數(shù) error 為錯(cuò)誤信息
client.on('error', function (error) { console.log(error) })
message
當(dāng)客戶端收到一個(gè)發(fā)布過來的 Payload 時(shí)觸發(fā),其中包含三個(gè)參數(shù),topic、payload 和 packet,其中 topic 為接收到的消息的 topic,payload 為接收到的消息內(nèi)容,packet 為 MQTT 報(bào)文信息,其中包含 QoS、retain 等信息
client.on('message', function (topic, payload, packet) { // Payload is Buffer console.log(`Topic: ${topic}, Message: ${payload.toString()}, QoS: ${packet.qos}`) })
Client 方法
Client 除監(jiān)聽事件外,也內(nèi)置一些方法,用來進(jìn)行發(fā)布訂閱的操作等,以下列舉一些常用的方法。
Client.publish(topic, message, [options], [callback])
向某一 topic 發(fā)布消息的函數(shù)方法,其中包含四個(gè)參數(shù):
// 向 testtopic 主題發(fā)送一條 QoS 為 0 的測試消息 client.publish('testtopic', 'Hello, MQTT!', { qos: 0, retain: false }, function (error) { if (error) { console.log(error) } else { console.log('Published') } })
- topic: 要發(fā)送的主題,為字符串
- message: 要發(fā)送的主題的下的消息,可以是字符串或者是 Buffer
- options: 可選值,發(fā)布消息時(shí)的配置信息,主要是設(shè)置發(fā)布消息時(shí)的 QoS、Retain 值等。
- callback: 發(fā)布消息后的回調(diào)函數(shù),參數(shù)為 error,當(dāng)發(fā)布失敗時(shí),該參數(shù)才存在
Client.subscribe(topic/topic array/topic object, [options], [callback])
訂閱一個(gè)或者多個(gè) topic 的方法,當(dāng)連接成功需要訂閱主題來獲取消息,該方法包含三個(gè)參數(shù):
// 訂閱一個(gè)名為 testtopic QoS 為 0 的 Topic client.subscribe('testtopic', { qos: 0 }, function (error, granted) { if (error) { console.log(error) } else { console.log(`${granted[0].topic} was subscribed`) } })
- topic: 可傳入一個(gè)字符串,或者一個(gè)字符串?dāng)?shù)組,也可以是一個(gè) topic 對象,
{'test1': {qos: 0}, 'test2': {qos: 1}}
- options: 可選值,訂閱 Topic 時(shí)的配置信息,主要是填寫訂閱的 Topic 的 QoS 等級的
- callback: 訂閱 Topic 后的回調(diào)函數(shù),參數(shù)為 error 和 granted,當(dāng)訂閱失敗時(shí) error 參數(shù)才存在, granted 是一個(gè) {topic, qos} 的數(shù)組,其中 topic 是一個(gè)被訂閱的主題,qos 是 Topic 是被授予的 QoS 等級
Client.unsubscribe(topic/topic array, [options], [callback])
取消訂閱單個(gè)主題或多個(gè)主題,該方法包含三個(gè)參數(shù):
// 取消訂閱名為 testtopic 的 Topic client.unsubscribe('testtopic', function (error) { if (error) { console.log(error) } else { console.log('Unsubscribed') } })
- topic: 可傳入一個(gè)字符串或一個(gè)字符串?dāng)?shù)組
- options: 可選值,取消訂閱時(shí)的配置信息
- callback: 取消訂閱時(shí)的回調(diào)函數(shù),參數(shù)為 error,當(dāng)取消訂閱失敗時(shí) error 參數(shù)才存在
Client.end([force], [options], [callback])
關(guān)閉客戶端,該方法包含三個(gè)參數(shù):
client.end()
- force: 設(shè)置為 true 時(shí)將立即關(guān)閉客戶端,而無需等待斷開連接的消息被接受。這個(gè)參數(shù)是可選的,默認(rèn)為 false。注意:使用該值為 true 時(shí),Broker 無法接收到 disconnect 的報(bào)文
- options: 可選值,關(guān)閉客戶端時(shí)的配置信息,主要是可以配置 reasonCode,斷開連接時(shí)的 Reason Code
- callback: 當(dāng)客戶端關(guān)閉時(shí)的回調(diào)函數(shù)
總結(jié)
至此就簡單的介紹了 MQTT.js 一些常用的 API 的使用方法等,具體在實(shí)際項(xiàng)目中的使用請參考以下鏈接:
如何在 Electron 項(xiàng)目中使用 MQTT
到此這篇關(guān)于MQTT.js 入門教程的文章就介紹到這了,更多相關(guān)MQTT.js 入門內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線推送的方法
- Django連接MQTT的示例代碼
- vue3+vite2+mqtt連接遇到的坑及解決
- vue3使用mqtt的示例代碼
- 詳解JS HTML Web端使用MQTT通訊測試
- VUE3+mqtt封裝解決多頁面使用需重復(fù)連接等問題(附實(shí)例)
- 解決spring-integration-mqtt頻繁報(bào)Lost connection錯(cuò)誤問題
- JS?連接MQTT的使用方法
- 使用java?實(shí)現(xiàn)mqtt兩種常用方式
- Android MQTT與WebSocket協(xié)議詳細(xì)講解
- MQTT Client實(shí)現(xiàn)消息推送功能的方法詳解
相關(guān)文章
詳解JavaScript中new操作符的解析和實(shí)現(xiàn)
這篇文章主要介紹了JavaScript中new操作符的解析和實(shí)現(xiàn),幫助大家更好的理解和學(xué)習(xí)JavaScript,感興趣的朋友可以了解下2020-09-09微信小程序授權(quán)登陸及每次檢查是否授權(quán)實(shí)例代碼
這篇文章主要介紹了關(guān)于微信小程序授權(quán)登陸及每次檢查是否授權(quán),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09JS實(shí)現(xiàn)三級折疊菜單特效,其它級可自動(dòng)收縮
這篇文章主要介紹了JS實(shí)現(xiàn)三級折疊菜單特效,其它級可自動(dòng)收縮,需要的朋友可以參考下2015-08-08javascript:;與javascript:void(0)使用介紹
有時(shí)候我們在編寫js過程中,需要觸發(fā)事件而不需要返回值,那么就可能需要這樣的寫法2013-06-06