JS?連接MQTT的使用方法
本文章是介紹 mqtt.js 的使用方法
一、說(shuō)明
- 本文章使用的版本是
4.1.x
,沒(méi)用最新版的原因是4.2.x
以上版本會(huì)報(bào)錯(cuò),具體報(bào)錯(cuò)可以查看文末介紹。 - 使用的
4.1.x
版本地址:https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js - 如果遇到
無(wú)法連接/錯(cuò)誤提示 WebSocket connection to ……
的問(wèn)題,請(qǐng)看我另一篇文章,其中記錄了我多次用到,遇見(jiàn)的連接問(wèn)題,點(diǎn)擊查看。
二、安裝
CDN 安裝
<script src="https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js"></script> <script> // 會(huì)在全局初始化一個(gè) mqtt 變量,直接使用就可以 console.log(mqtt) </script>
npm 安裝
npm install mqtt --save
npm 安裝后使用
// 頁(yè)面使用,直接 import 就可以 import mqtt from 'mqtt';
三、使用
常用方式 下面有詳細(xì)介紹
// 連接地址,有很多連接失敗都是因?yàn)榈刂窙](méi)寫(xiě)對(duì) const connectUrl = `ws://XXXX/mqtt/ws`; // 客戶端ID const clientId = `mqtt_${Math.random().toString(16).slice(3)}`; // 連接設(shè)置 let options = { clean: true, // 保留會(huì)話 connectTimeout: 4000, // 超時(shí)時(shí)間 reconnectPeriod: 1000, // 重連時(shí)間間隔 // 認(rèn)證信息 clientId, username: 'zhongketianji', password: 'zhongketianji123', } // 需要訂閱的主題 const topic = '/mqtt_backend/format_tracking/Uibox.car190'; const topic1 = '/mqtt_backend/format_tracking/Uibox.car191'; // 創(chuàng)建客戶端 var client = mqtt.connect(connectUrl, options); // 成功連接后觸發(fā)的回調(diào) client.on('connect', () => { console.log('已經(jīng)連接成功'); // 訂閱主題,這里可以訂閱多個(gè)主題 client.subscribe([topic, topic1], () => { console.log(`訂閱了主題 ${[topic, topic1].join('和')}`) }) }); // 當(dāng)客戶端收到一個(gè)發(fā)布過(guò)來(lái)的消息時(shí)觸發(fā)回調(diào) /** * topic:收到的報(bào)文的topic * message:收到的數(shù)據(jù)包的負(fù)載playload * packet:MQTT 報(bào)文信息,其中包含 QoS、retain 等信息 */ client.on('message', function (topic, message, packet) { // 這里有可能拿到的數(shù)據(jù)格式是Uint8Array格式,可以直接用toString轉(zhuǎn)成字符串 // let data = JSON.parse(message.toString()); console.log("獲取到的數(shù)據(jù):", message) console.log("數(shù)據(jù)對(duì)應(yīng)訂閱主題:", topic) console.log("獲取到的數(shù)據(jù)包:", packet) }); // 關(guān)閉客戶端(斷開(kāi)連接) client.end(); // 發(fā)送信息給 topic(主題) client.publish(topic, '這是給topic發(fā)送的信息');
options 連接設(shè)置(常用)
屬性 | 說(shuō)明 |
---|---|
keepalive | 單位為秒,數(shù)值類型,默認(rèn)為 60 秒,設(shè)置為 0 時(shí)禁止。用于解決半連接問(wèn)題,在該時(shí)間內(nèi)是否接收兩次傳輸 |
clientId | 默認(rèn)為 ‘mqttjs_’ + Math.random().toString(16).substr(2, 8),可自定義修改,字符串類型 |
protocolVersion | MQTT 協(xié)議版本號(hào),默認(rèn)為 4(v3.1.1)可以修改為 3(v3.1)和 5(v5.0) |
clean | 是否清除會(huì)話,默認(rèn)為 true。當(dāng)設(shè)置為 true 時(shí),斷開(kāi)連接后將清除會(huì)話,訂閱過(guò)的 Topic 也將失效。當(dāng)設(shè)置為 false 時(shí),離線狀態(tài)下也能收到 QoS 為 1 和 2 的消息 |
reconnectPeriod | 重連間隔時(shí)間,單位為毫秒,默認(rèn)為 1000 毫秒,注意:當(dāng)設(shè)置為 0 以后將取消自動(dòng)重連 |
connectTimeout | 連接超時(shí)時(shí)長(zhǎng),收到 CONNACK 前的等待時(shí)間,單位為毫秒,默認(rèn) 30000 毫秒 |
username | 認(rèn)證用戶名,如果 Broker 要求用戶名認(rèn)證的話,請(qǐng)?jiān)O(shè)置該值 |
password | 認(rèn)證密碼,如果 Broker 要求密碼認(rèn)證的話,請(qǐng)?jiān)O(shè)置該值 |
will | 遺囑消息,一個(gè)可配置的對(duì)象值,當(dāng)客戶端非正常斷開(kāi)連接時(shí),Broker 就會(huì)向遺囑 Topic 里面發(fā)布一條消息。 |
will 格式:
will: { topic: 'WillMsg', // 發(fā)布消息的主題 payload: 'Connection Closed abnormally!', // 要發(fā)布的消息 qos: 0, // 消息等級(jí) retain: false // 保留消息標(biāo)識(shí) },
Client 監(jiān)聽(tīng) (on方法)
// 成功連接后觸發(fā)的回調(diào) client.on('connect', () => { console.log('已經(jīng)連接成功'); }); // 當(dāng)客戶端收到一個(gè)發(fā)布過(guò)來(lái)的消息時(shí)觸發(fā)回調(diào) /** * topic:收到的數(shù)據(jù)包的topic * message:收到的數(shù)據(jù)包的負(fù)載playload * packet:MQTT 報(bào)文信息,其中包含 QoS、retain 等信息 */ client.on('message', function (topic, message, packet) { // 這里有可能拿到的數(shù)據(jù)格式是Uint8Array格式,可以直接用toString轉(zhuǎn)成字符串 // let data = JSON.parse(message.toString()); console.log("獲取到的數(shù)據(jù):", data_190) console.log("數(shù)據(jù)對(duì)應(yīng)訂閱主題:", topic) console.log("獲取到的數(shù)據(jù)包:", packet) }); // 當(dāng)重新連接啟動(dòng)觸發(fā)回調(diào) client.on('reconnect', () => { console.log("正在重新連接") }); // 連接斷開(kāi)后觸發(fā)的回調(diào) client.on("close",function () { console.log("已斷開(kāi)連接") }); // 在收到 Broker(消息服務(wù)器) 發(fā)送過(guò)來(lái)的斷開(kāi)連接的報(bào)文時(shí)觸發(fā)的回調(diào),參數(shù) packet 即為斷開(kāi)連接時(shí)接收到的報(bào)文。MQTT 5.0特性 client.on("disconnect",function (packet) { console.log("從broker接收到斷開(kāi)連接的報(bào)文:"+packet); }); // 客戶端脫機(jī)下線觸發(fā)回調(diào) client.on("offline",function () { console.log("您已斷開(kāi)連接,請(qǐng)檢查網(wǎng)絡(luò)") }); // 當(dāng)客戶端無(wú)法成功連接時(shí)或發(fā)生解析錯(cuò)誤時(shí)觸發(fā)的回調(diào),參數(shù) error 為錯(cuò)誤信息 client.on("error",(error) =>{ console.log("客戶端出現(xiàn)錯(cuò)誤:", error); }); //當(dāng)客戶端發(fā)送任何數(shù)據(jù)包時(shí)發(fā)出。這包括publish()以及MQTT用于管理訂閱和連接的包 client.on("packetsend",(packet)=>{ console.log("客戶端已發(fā)出報(bào)文", packet); }); //當(dāng)客戶端接收到任何報(bào)文時(shí)發(fā)出。這包括來(lái)自訂閱主題的信息包以及MQTT用于管理訂閱和連接的信息 client.on("packetreceive",(packet)=>{ // 會(huì)在 client.on('message', function (topic, message, packet) {}); 之前觸發(fā) console.log("客戶端接收?qǐng)?bào)文", packet); });
Client 方法(除on方法)
向某一 topic(主題) 發(fā)布消息
Client.publish(topic, message, [options], [callback])
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ù)才存在
// 向 test 主題發(fā)送一條 QoS 為 0 的消息 client.publish('test', '這是一條信息', { qos: 0, retain: false }, function (error) { if (error) { console.log(error) } else { console.log('Published') } })
訂閱一個(gè)或者多個(gè) topic(主題) 的方法(當(dāng)連接成功后需要訂閱主題來(lái)獲取消息)
Client.subscribe(topic/topic array/topic object, [options], [callback])
topic: 可傳入一個(gè)字符串,或者一個(gè)字符串?dāng)?shù)組,也可以是一個(gè)
topic
對(duì)象,例如:{‘test1’: {qos: 0}, ‘test2’: {qos: 1}}
options: 可選值,訂閱Topic
時(shí)的配置信息,主要是填寫(xiě)訂閱的Topic
的QoS
等級(jí)的
callback: 訂閱Topic
后的回調(diào)函數(shù),參數(shù)為error
和granted
,當(dāng)訂閱失敗時(shí)error
參數(shù)才存在,granted
是一個(gè) {topic, qos} 的數(shù)組,其中topic
是一個(gè)被訂閱的主題,qos
是Topic
是被授予的QoS
等級(jí)
// 訂閱一個(gè)名為 test 且 QoS 為 0 的 Topic client.subscribe('test', { qos: 0 }, function (error, granted) { if (error) { console.log("訂閱失敗:", error) } else { console.log("已訂閱:", granted[0].topic) } })
取消訂閱單個(gè) topic(主題)或多個(gè) topic(主題)
Client.unsubscribe(topic/topic array, [options], [callback])
topic: 可傳入一個(gè)字符串或一個(gè)字符串?dāng)?shù)組
options: 可選值,取消訂閱時(shí)的配置信息
callback: 取消訂閱時(shí)的回調(diào)函數(shù),參數(shù)為error
,當(dāng)取消訂閱失敗時(shí)error
參數(shù)才存在
// 取消訂閱名為 test 的 Topic client.unsubscribe('test', function (error) { if (error) { console.log(error) } else { console.log('已取消訂閱') } })
關(guān)閉客戶端
Client.end([force], [options], [callback])
force: 設(shè)置為
true
時(shí)將立即關(guān)閉客戶端,而無(wú)需等待斷開(kāi)連接的消息被接受。這個(gè)參數(shù)是可選的,默認(rèn)為false
。注意: 使用該值為true
時(shí),Broker
無(wú)法接收到disconnect
的報(bào)文
options: 可選值,關(guān)閉客戶端時(shí)的配置信息,主要是可以配置reasonCode
,斷開(kāi)連接時(shí)的Reason Code
callback: 當(dāng)客戶端關(guān)閉時(shí)的回調(diào)函數(shù)
client.end();
四、測(cè)試
EMQX 提供的 免費(fèi)公共 MQTT 服務(wù)器,該服務(wù)基于 EMQX 的 MQTT 物聯(lián)網(wǎng)云平臺(tái) 創(chuàng)建。
服務(wù)器接入信息如下:
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'; //成功連接后觸發(fā)的回調(diào) client.on('connect', () => { console.log('已經(jīng)連接成功'); // 這里可以訂閱多個(gè)主題 client.subscribe([topic], () => { console.log(`訂閱了主題 ${topic}`) }) }); // 當(dāng)客戶端收到一個(gè)發(fā)布過(guò)來(lái)的消息時(shí)觸發(fā)回調(diào) client.on('message', function (message) { // 這里有可能拿到的數(shù)據(jù)格式是Uint8Array格式,所以可以直接用toString轉(zhuǎn)成字符串 // let data = JSON.parse(message.toString()); console.log("返回的數(shù)據(jù):", message) }); // 連接斷開(kāi)后觸發(fā)的回調(diào) client.on("close", function () { console.log("已斷開(kāi)連接") });
五、測(cè)試結(jié)果
PS:關(guān)于mqtt.js報(bào)錯(cuò) n.createConnection is not a function
原因: 這個(gè)是版本問(wèn)題,4.2.x 以上(目前我使用最新版也是這個(gè)問(wèn)題,可能后續(xù)會(huì)改進(jìn))
解決方案: 使用低版本的,我用的4.1.x就可以。(后面有CDN地址)
這里是連接成功后輸出了一下client。
VUE的解決方案:
看網(wǎng)上其他的說(shuō)vue安裝,不僅需要修改版本,還需要將版本前面的^
去掉(packpage.json里),不過(guò)沒(méi)用vue測(cè)試,大家可以試試(這里截了一張其他博客的圖)
這里可以選擇版本:https://www.bootcdn.cn/mqtt/
我用的地址:https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js
到此這篇關(guān)于JS 連接MQTT的使用方法的文章就介紹到這了,更多相關(guān)MQTT使用方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線推送的方法
- Django連接MQTT的示例代碼
- vue3+vite2+mqtt連接遇到的坑及解決
- vue3使用mqtt的示例代碼
- MQTT.js 入門(mén)使用教程
- 詳解JS HTML Web端使用MQTT通訊測(cè)試
- VUE3+mqtt封裝解決多頁(yè)面使用需重復(fù)連接等問(wèn)題(附實(shí)例)
- 解決spring-integration-mqtt頻繁報(bào)Lost connection錯(cuò)誤問(wèn)題
- 使用java?實(shí)現(xiàn)mqtt兩種常用方式
- Android MQTT與WebSocket協(xié)議詳細(xì)講解
- MQTT Client實(shí)現(xiàn)消息推送功能的方法詳解
相關(guān)文章
基于leaflet.js實(shí)現(xiàn)修改地圖主題樣式的流程分析
這篇文章主要介紹了基于leaflet.js實(shí)現(xiàn)修改地圖主題樣式的流程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05JavaScript實(shí)現(xiàn)瀑布動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)瀑布動(dòng)畫(huà),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06解決iframe嵌套第三方網(wǎng)址不能訪問(wèn)的各種報(bào)錯(cuò)
在一些場(chǎng)景下,我們的網(wǎng)站需要通過(guò)iframe標(biāo)簽嵌入第三方廠家的頁(yè)面,這時(shí)候就得通過(guò)iframe標(biāo)簽去引入需要嵌入網(wǎng)頁(yè)的網(wǎng)址了,這篇文章主要給大家介紹了關(guān)于解決iframe嵌套第三方網(wǎng)址不能訪問(wèn)的各種報(bào)錯(cuò),需要的朋友可以參考下2024-09-09擴(kuò)展JS Date對(duì)象時(shí)間格式化功能的小例子
這篇文章主要介紹了擴(kuò)展JS Date對(duì)象時(shí)間格式化功能,有需要的朋友可以參考一下2013-12-12JavaScript 錯(cuò)誤處理與調(diào)試經(jīng)驗(yàn)總結(jié)
在Web開(kāi)發(fā)過(guò)程中,編寫(xiě)JavaScript程序時(shí)或多或少會(huì)遇到各種各樣的錯(cuò)誤,有語(yǔ)法錯(cuò)誤,邏輯錯(cuò)誤。如果是一小段代碼,可以通過(guò)仔細(xì)檢查來(lái)排除錯(cuò)誤,但如果程序稍微復(fù)雜點(diǎn),調(diào)試JS便成為一個(gè)令Web開(kāi)發(fā)者很頭痛的問(wèn)題。2010-08-08javascript執(zhí)行上下文、變量對(duì)象實(shí)例分析
這篇文章主要介紹了javascript執(zhí)行上下文、變量對(duì)象,結(jié)合實(shí)例形式分析了javascript執(zhí)行上下文、變量對(duì)象相關(guān)概念、原理、用法與操作注意事項(xiàng),需要的朋友可以參考下2020-04-04moment.js 計(jì)算當(dāng)前一周、一月對(duì)應(yīng)日期的實(shí)例
這篇文章主要介紹了moment.js 計(jì)算當(dāng)前一周、一月對(duì)應(yīng)日期的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12原生JavaScript實(shí)現(xiàn)合并多個(gè)數(shù)組示例
這篇文章主要介紹了原生的JavaScript及jquery實(shí)現(xiàn)合并多個(gè)數(shù)組,很簡(jiǎn)單,很實(shí)用,大家可以看看2014-09-09