在Vue中使用MQTT實(shí)現(xiàn)通信過(guò)程
一、安裝 MQTT 客戶端庫(kù)
我們使用 mqtt.js,它是一個(gè)支持瀏覽器環(huán)境的 MQTT 客戶端庫(kù)。
通過(guò)以下命令安裝:
npm install mqtt
二、創(chuàng)建 MQTT 連接工具類
為了方便管理和復(fù)用 MQTT 客戶端,我們創(chuàng)建一個(gè)工具類 mqttClient.js,放在 src/utils 目錄下:
import mqtt from 'mqtt';
class MQTTClient {
constructor(options) {
this.client = null;
this.messages = [];
this.subscribers = {};
this.defaultOptions = {
clientId: 'vue-client_' + Math.random().toString(16).substr(2, 8),
clean: true,
connectTimeout: 4000,
//username: '賬號(hào)',
//password: '密碼'
};
this.options = { ...this.defaultOptions, ...options };
}
connect(brokerUrl) {
return new Promise((resolve, reject) => {
try {
this.client = mqtt.connect(brokerUrl, this.options);
this.client.on('connect', () => {
console.log('連接成功');
resolve(this.client);
});
this.client.on('error', (err) => {
console.error('連接失敗:', err);
reject(err);
});
this.client.on('message', (topic, payload) => {
const message = {
topic: topic,
content: payload.toString()
};
this.messages.push(message);
// 如果有訂閱者,通知所有訂閱了該主題的回調(diào)
if (this.subscribers[topic]) {
this.subscribers[topic].forEach(callback => callback(message));
}
});
this.client.on('close', () => {
console.log('MQTT connection closed');
});
} catch (err) {
reject(err);
}
});
}
// 訂閱主題
subscribe(topic, callback, qos = 0) {
if (!this.client || this.client.connected === false) {
// console.error('MQTT not connected');
return;
}
this.client.subscribe(topic, { qos }, (err) => {
if (!err) {
console.log(`Subscribed to ${topic}`);
// 存儲(chǔ)訂閱回調(diào)
if (!this.subscribers[topic]) {
this.subscribers[topic] = [];
}
this.subscribers[topic].push(callback);
}
});
}
// 取消訂閱指定主題的方法
unsubscribe(topic) {
if (!this.client || this.client.connected === false) {
console.error('MQTT not connected');
return;
}
this.client.unsubscribe(topic, (err) => {
if (!err) {
console.log(`Unsubscribed from ${topic}`);
// 移除訂閱回調(diào)
if (this.subscribers[topic]) {
delete this.subscribers[topic];
}
}
});
}
// 發(fā)送消息
publish(topic, message, qos = 0, retain = false) {
if (!this.client || this.client.connected === false) {
console.error('MQTT not connected');
return;
}
this.client.publish(topic, message, { qos, retain }, (err) => {
if (err) {
console.error('Publish error:', err);
}
});
}
// 取消連接
disconnect() {
if (this.client) {
this.client.end();
this.client = null;
}
}
getMessages() {
return [...this.messages];
}
clearMessages() {
this.messages = [];
}
}
export default MQTTClient;
三、在 Vue 組件中使用
我們創(chuàng)建一個(gè) Vue 組件來(lái)使用 MQTT 客戶端
<template>
<div>
<h3>接收的 MQTT 消息:</h3>
<ul>
<li v-for="(msg, index) in messages" :key="index">
{{ msg.topic }}: {{ msg.content }}
</li>
</ul>
<!-- <ul>
<li v-for="(msg, index) in top2" :key="index">
{{ msg.topic }}: {{ msg.content }}
</li>
</ul> -->
<button @click="publishMessage">發(fā)送消息</button>
</div>
</template>
<script>
import MQTTClient from '@/util/mqtt';
export default {
data() {
return {
mqttClient: null,
messages: [],
top2:[]
};
},
mounted() {
this.initMQTT();
},
methods: {
initMQTT() {
this.mqttClient = new MQTTClient();
// 連接到 MQTT 代理
const url="ws://"+"你的地址"+":8083/mqtt" //例如ws://172.18.14.167:8083/mqtt
this.mqttClient.connect(url)
.then(() => {
console.log('訂閱成功');
// 訂閱主題
this.mqttClient.subscribe('kpmqqt-lims-data-top1', (message) => {
this.messages.push(message);
});
// this.mqttClient.subscribe('kpmqqt-lims-data-top2', (message) => {
// this.top2.push(message);
// });
})
.catch(err => {
console.error('MQTT connection failed:', err);
});
},
publishMessage() {
if (this.mqttClient) {
this.mqttClient.publish('kpmqqt-lims-data-top1', 'Hello from 測(cè)試Vue2!');
// this.mqttClient.publish('kpmqqt-lims-data-top2', 'Hello from 測(cè)試!');
} else {
console.error('MQTT client not initialized');
}
}
},
beforeDestroy() {
if (this.mqttClient) {
this.mqttClient.disconnect();
}
}
};
</script>
四、或者直接在頁(yè)面使用
<template>
<div>
<h3>接收的 MQTT 消息:</h3>
<ul>
<li v-for="(msg, index) in messages" :key="index">
{{ msg.topic }}: {{ msg.content }}
</li>
</ul>
</div>
</template>
<script>
import mqtt from 'mqtt';
export default {
data() {
return {
client: null,
messages: []
};
},
mounted() {
this.initMQTT();
},
methods: {
initMQTT() {
const options = {
clientId: 'vue-client_' + Math.random().toString(16).substr(2, 8),
clean: true,
connectTimeout: 4000
};
const url="ws://"+"你的地址"+":8083/mqtt" //例如ws://172.18.14.167:8083/mqtt
this.client = mqtt.connect(url, options);
this.client.on('connect', (e) => {
this.subscribeTopics();
});
this.client.on('message', (topic, payload) => {
this.messages.push({
topic: topic,
content: payload.toString()
});
});
},
subscribeTopics() {
this.client.subscribe(['sensor/#'], { qos: 1 });
}
},
beforeDestroy() {
if (this.client) {
this.client.end();
}
}
};
</script>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Vue如何進(jìn)行表單聯(lián)動(dòng)與級(jí)聯(lián)選擇
表單聯(lián)動(dòng)和級(jí)聯(lián)選擇是Vue.js中常見(jiàn)的功能,在下面的文章中,我們將討論如何在Vue.js中實(shí)現(xiàn)表單聯(lián)動(dòng)和級(jí)聯(lián)選擇,感興趣的小伙伴可以了解一下2023-06-06
vue實(shí)現(xiàn)拖拽的簡(jiǎn)單案例 不超出可視區(qū)域
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)拖拽的簡(jiǎn)單案例,不超出可視區(qū)域,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
Vue項(xiàng)目如何設(shè)置反向代理和cookie設(shè)置問(wèn)題
這篇文章主要介紹了Vue項(xiàng)目如何設(shè)置反向代理和cookie設(shè)置問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
解決在vue+webpack開發(fā)中出現(xiàn)兩個(gè)或多個(gè)菜單公用一個(gè)組件問(wèn)題
這篇文章主要介紹了在vue+webpack實(shí)際開發(fā)中出現(xiàn)兩個(gè)或多個(gè)菜單公用一個(gè)組件的解決方案,需要的朋友可以參考下2017-11-11
Vue filter 過(guò)濾當(dāng)前時(shí)間 實(shí)現(xiàn)實(shí)時(shí)更新效果
這篇文章主要介紹了Vue filter 過(guò)濾當(dāng)前時(shí)間 實(shí)現(xiàn)實(shí)時(shí)更新效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12

