JS?連接MQTT的使用方法
本文章是介紹 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 --save
npm 安裝后使用
// 頁面使用,直接 import 就可以 import mqtt from 'mqtt';
三、使用
常用方式 下面有詳細介紹
// 連接地址,有很多連接失敗都是因為地址沒寫對
const connectUrl = `ws://XXXX/mqtt/ws`;
// 客戶端ID
const clientId = `mqtt_${Math.random().toString(16).slice(3)}`;
// 連接設(shè)置
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';
// 創(chuàng)建客戶端
var client = mqtt.connect(connectUrl, options);
// 成功連接后觸發(fā)的回調(diào)
client.on('connect', () => {
console.log('已經(jīng)連接成功');
// 訂閱主題,這里可以訂閱多個主題
client.subscribe([topic, topic1], () => {
console.log(`訂閱了主題 ${[topic, topic1].join('和')}`)
})
});
// 當客戶端收到一個發(fā)布過來的消息時觸發(fā)回調(diào)
/**
* topic:收到的報文的topic
* message:收到的數(shù)據(jù)包的負載playload
* packet:MQTT 報文信息,其中包含 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ù)對應(yīng)訂閱主題:", topic)
console.log("獲取到的數(shù)據(jù)包:", packet)
});
// 關(guān)閉客戶端(斷開連接)
client.end();
// 發(fā)送信息給 topic(主題)
client.publish(topic, '這是給topic發(fā)送的信息');options 連接設(shè)置(常用)
| 屬性 | 說明 |
|---|---|
| keepalive | 單位為秒,數(shù)值類型,默認為 60 秒,設(shè)置為 0 時禁止。用于解決半連接問題,在該時間內(nèi)是否接收兩次傳輸 |
| clientId | 默認為 ‘mqttjs_’ + Math.random().toString(16).substr(2, 8),可自定義修改,字符串類型 |
| protocolVersion | MQTT 協(xié)議版本號,默認為 4(v3.1.1)可以修改為 3(v3.1)和 5(v5.0) |
| clean | 是否清除會話,默認為 true。當設(shè)置為 true 時,斷開連接后將清除會話,訂閱過的 Topic 也將失效。當設(shè)置為 false 時,離線狀態(tài)下也能收到 QoS 為 1 和 2 的消息 |
| reconnectPeriod | 重連間隔時間,單位為毫秒,默認為 1000 毫秒,注意:當設(shè)置為 0 以后將取消自動重連 |
| connectTimeout | 連接超時時長,收到 CONNACK 前的等待時間,單位為毫秒,默認 30000 毫秒 |
| username | 認證用戶名,如果 Broker 要求用戶名認證的話,請設(shè)置該值 |
| password | 認證密碼,如果 Broker 要求密碼認證的話,請設(shè)置該值 |
| will | 遺囑消息,一個可配置的對象值,當客戶端非正常斷開連接時,Broker 就會向遺囑 Topic 里面發(fā)布一條消息。 |
will 格式:
will: {
topic: 'WillMsg', // 發(fā)布消息的主題
payload: 'Connection Closed abnormally!', // 要發(fā)布的消息
qos: 0, // 消息等級
retain: false // 保留消息標識
},Client 監(jiān)聽 (on方法)
// 成功連接后觸發(fā)的回調(diào)
client.on('connect', () => {
console.log('已經(jīng)連接成功');
});
// 當客戶端收到一個發(fā)布過來的消息時觸發(fā)回調(diào)
/**
* topic:收到的數(shù)據(jù)包的topic
* message:收到的數(shù)據(jù)包的負載playload
* packet:MQTT 報文信息,其中包含 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ù)對應(yīng)訂閱主題:", topic)
console.log("獲取到的數(shù)據(jù)包:", packet)
});
// 當重新連接啟動觸發(fā)回調(diào)
client.on('reconnect', () => {
console.log("正在重新連接")
});
// 連接斷開后觸發(fā)的回調(diào)
client.on("close",function () {
console.log("已斷開連接")
});
// 在收到 Broker(消息服務(wù)器) 發(fā)送過來的斷開連接的報文時觸發(fā)的回調(diào),參數(shù) packet 即為斷開連接時接收到的報文。MQTT 5.0特性
client.on("disconnect",function (packet) {
console.log("從broker接收到斷開連接的報文:"+packet);
});
// 客戶端脫機下線觸發(fā)回調(diào)
client.on("offline",function () {
console.log("您已斷開連接,請檢查網(wǎng)絡(luò)")
});
// 當客戶端無法成功連接時或發(fā)生解析錯誤時觸發(fā)的回調(diào),參數(shù) error 為錯誤信息
client.on("error",(error) =>{
console.log("客戶端出現(xiàn)錯誤:", error);
});
//當客戶端發(fā)送任何數(shù)據(jù)包時發(fā)出。這包括publish()以及MQTT用于管理訂閱和連接的包
client.on("packetsend",(packet)=>{
console.log("客戶端已發(fā)出報文", packet);
});
//當客戶端接收到任何報文時發(fā)出。這包括來自訂閱主題的信息包以及MQTT用于管理訂閱和連接的信息
client.on("packetreceive",(packet)=>{
// 會在 client.on('message', function (topic, message, packet) {}); 之前觸發(fā)
console.log("客戶端接收報文", packet);
});
Client 方法(除on方法)
向某一 topic(主題) 發(fā)布消息
Client.publish(topic, message, [options], [callback])
topic: 要發(fā)送的主題(字符串)
message: 要發(fā)送的主題的下的消息,可以是字符串或者是Buffer
options: 可選值,發(fā)布消息時的配置信息,主要是設(shè)置發(fā)布消息時的QoS、Retain值等。
callback: 發(fā)布消息后的回調(diào)函數(shù),參數(shù)為error,當發(fā)布失敗時,該參數(shù)才存在
// 向 test 主題發(fā)送一條 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: 可傳入一個字符串,或者一個字符串數(shù)組,也可以是一個
topic對象,例如:{‘test1’: {qos: 0}, ‘test2’: {qos: 1}}
options: 可選值,訂閱Topic時的配置信息,主要是填寫訂閱的Topic的QoS等級的
callback: 訂閱Topic后的回調(diào)函數(shù),參數(shù)為error和granted,當訂閱失敗時error參數(shù)才存在,granted是一個 {topic, qos} 的數(shù)組,其中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(主題)或多個 topic(主題)
Client.unsubscribe(topic/topic array, [options], [callback])
topic: 可傳入一個字符串或一個字符串數(shù)組
options: 可選值,取消訂閱時的配置信息
callback: 取消訂閱時的回調(diào)函數(shù),參數(shù)為error,當取消訂閱失敗時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時將立即關(guān)閉客戶端,而無需等待斷開連接的消息被接受。這個參數(shù)是可選的,默認為false。注意: 使用該值為true時,Broker無法接收到disconnect的報文
options: 可選值,關(guān)閉客戶端時的配置信息,主要是可以配置reasonCode,斷開連接時的Reason Code
callback: 當客戶端關(guān)閉時的回調(diào)函數(shù)
client.end();
四、測試
EMQX 提供的 免費公共 MQTT 服務(wù)器,該服務(wù)基于 EMQX 的 MQTT 物聯(lián)網(wǎng)云平臺 創(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)連接成功');
// 這里可以訂閱多個主題
client.subscribe([topic], () => {
console.log(`訂閱了主題 ${topic}`)
})
});
// 當客戶端收到一個發(fā)布過來的消息時觸發(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)
});
// 連接斷開后觸發(fā)的回調(diào)
client.on("close", function () {
console.log("已斷開連接")
});
五、測試結(jié)果

PS:關(guān)于mqtt.js報錯 n.createConnection is not a function

原因: 這個是版本問題,4.2.x 以上(目前我使用最新版也是這個問題,可能后續(xù)會改進)
解決方案: 使用低版本的,我用的4.1.x就可以。(后面有CDN地址)
這里是連接成功后輸出了一下client。

VUE的解決方案:
看網(wǎng)上其他的說vue安裝,不僅需要修改版本,還需要將版本前面的^去掉(packpage.json里),不過沒用vue測試,大家可以試試(這里截了一張其他博客的圖)

這里可以選擇版本: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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 在Node.js下運用MQTT協(xié)議實現(xiàn)即時通訊及離線推送的方法
- Django連接MQTT的示例代碼
- vue3+vite2+mqtt連接遇到的坑及解決
- vue3使用mqtt的示例代碼
- MQTT.js 入門使用教程
- 詳解JS HTML Web端使用MQTT通訊測試
- VUE3+mqtt封裝解決多頁面使用需重復(fù)連接等問題(附實例)
- 解決spring-integration-mqtt頻繁報Lost connection錯誤問題
- 使用java?實現(xiàn)mqtt兩種常用方式
- Android MQTT與WebSocket協(xié)議詳細講解
- MQTT Client實現(xiàn)消息推送功能的方法詳解
相關(guān)文章
關(guān)于javascript中dataset的問題小結(jié)
本文給大家介紹javascript中dataset的問題詳解,包括dataset的基礎(chǔ)用法,使用dataset的作用以及dataset的基礎(chǔ)操作等相關(guān)問題,對javascript dataset問題感興趣的朋友一起學(xué)習(xí)吧2015-11-11
關(guān)于JavaScript中name的意義沖突示例介紹
這篇文章主要介紹了關(guān)于JavaScript中name的意義沖突,需要的朋友可以參考下2014-05-05
js 數(shù)值轉(zhuǎn)換為3位逗號分隔的示例代碼
本篇文章主要是對js將數(shù)值轉(zhuǎn)換為3位逗號分隔的示例代碼進行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助2014-02-02
javascript實現(xiàn)iframe框架延時加載的方法
這篇文章主要介紹了javascript實現(xiàn)iframe框架延時加載的方法,可基于setTimeout實現(xiàn)這一功能,是非常實用的技巧,需要的朋友可以參考下2014-10-10
慕課網(wǎng)題目之js實現(xiàn)抽獎系統(tǒng)功能
這篇文章主要為大家詳細介紹了慕課網(wǎng)題目之js抽獎系統(tǒng)功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09

