服务器采用,RabbitMQ3.9,开启rabbitmq_web_mqtt,部署方法参考http://t.csdn.cn/Xe6Vg
0.安装相关组件
mqtt:用于连接
npm i "mqtt"
uuid:用于确定客户端唯一(非必须)
npm i "vue-uuid"
1.新建Mqtt.ts
import type { MqttClient, OnMessageCallback } from 'mqtt';
import * as mqtt from 'mqtt/dist/mqtt.min.js';
import { uuid } from 'vue-uuid';
class MQTT {
type: string; // 客户端分类(非必须)
url: string; // mqtt地址
client!: MqttClient;
constructor(type: string) {
this.type= type;
this.url = 'ws://192.168.x.x:15675/ws';// ws方式必须ws结尾
}
//初始化mqtt
init() {
const options = {
clean: true,
clientId: this.type+ "_" + uuid.v1(), // 客户端分类唯一
username: 'xxx',
password: 'xxx',
connectTimeout: 3000, // 超时时间
};
this.client = mqtt.connect(this.url, options);
this.client.on('error', (error: any) => {
console.log(this.url + "异常中断");
});
this.client.on('reconnect', (error: Error) => {
console.log(this.url + "重新连接");
});
}
//取消订阅
unsubscribes(topic: string) {
this.client.unsubscribe(topic, (error: Error) => {
if (!error) {
console.log(topic + '取消订阅成功');
} else {
console.log(topic + '取消订阅失败');
}
});
}
//连接
link(topic: string) {
this.client.on('connect', () => {
this.client.subscribe(topic, (error: any) => {
if (!error) {
console.log(topic + '订阅成功');
} else {
console.log(topic + '订阅失败');
}
});
});
}
//收到的消息
get(callback: OnMessageCallback) {
this.client.on('message', callback);
}
//结束链接
over() {
this.client.end();
}
}
export default MQTT;
2.新建UseMqtt.ts
import MQTT from './Mqtt';
import type { OnMessageCallback } from 'mqtt';
import {
ref,
onUnmounted
} from 'vue';
export default function useMqtt() {
const PublicMqtt = ref<MQTT | null>(null);
const linkList = Array<string>(); // 长连接的列表
const startMqtt = (type: string, callback: OnMessageCallback) => {
PublicMqtt.value = new MQTT(type);//创建连接
PublicMqtt.value.init();//初始化mqtt
linkList.forEach((topic) => { PublicMqtt.value?.unsubscribes(topic); PublicMqtt.value?.link(topic) });//订阅主题
getMessage(callback);
};
const addLink = (topic: string) => {
if (!linkList.includes(topic)) { // 简单地去重
linkList.push(topic);
PublicMqtt.value?.link(topic);
}
}
const Uint8ArrayToString = (fileData: Uint8Array) => {
var dataString = "";
for (var i = 0; i < fileData.length; i++) {
dataString += String.fromCharCode(fileData[i]);
}
return dataString
}
const getMessage = (callback: Function) => {
PublicMqtt.value?.get((t, m) => { callback(t, Uint8ArrayToString(m)); });
};
onUnmounted(() => {//页面销毁结束订阅
linkList.forEach((topic) => { PublicMqtt.value?.unsubscribes(topic) });
PublicMqtt.value?.over();
});
return {
startMqtt,
addLink
};
}
3.使用vue
<script setup lang="ts">
import UseMqtt from './UseMqtt';
const {
startMqtt,
addLink
} = UseMqtt();
// 创建一个连接
startMqtt("A", (topic, data) => {
console.log(topic);
console.log(data);
});
// 订阅多主题
addLink('a001');
addLink('a002');
</script>