话不多说,直接上代码
1.使用
import Mqtt from '@/utils/mqtt/index'
const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)
app.use(Mqtt, 'ws://47.xxx.14.180:8083/mqtt', {
keepalive: 60,
clientId: clientId,
protocolId: 'MQTT',
protocolVersion: 4,
clean: true,
username: '',
password: '',
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
will: ''
})
在setup方法中 '/ksjk/web/datashow/alarm' 是订阅主题地址
Reflect.set(proxy?.$options as Object, 'mqtts', {
'/ksjk/web/datashow/alarm': (topic: string, payload: Buffer) => {
try {
let data = JSON.parse(payload.toString());
console.log(`rx: ${payload}=>${data.type}`);
} catch (err) {
console.log(err);
}
},
});
2.进入正题
utils/mqtt/index.ts
import * as mqtt from 'mqtt/dist/mqtt.min';
import Emitter from "./Emitter";
import { App } from "vue";
export type MqttConnOpt = mqtt.IClientOptions
export class MQTT {
mqClient!: mqtt.MqttClient
private readonly store: any;
constructor(host: string, opts?: MqttConnOpt) {
this.connect(host, opts);
}
public subscribe(topic: string, qos: 0 | 1 | 2) {
if (this.isConnected()) {
console.log('订阅主题----', topic, qos);
this.mqClient.subscribe(topic, { qos })
}
}
public isConnected() {
return this.mqClient.connected == true
}
connect(host: string, opts?: MqttConnOpt) {
this.mqClient = mqtt.connect(host, opts);
this.mqClient.on('connect', () => {
console.log('连接成功---', this.mqClient.connected)
})
this.mqClient.on('message', (topic: string, payload: Buffer) => {
console.log('数据响应了---', topic);
Emitter.emit(topic, payload)
})
this.mqClient.on('error', (err: Error) => {
console.log('连接错误--------------------', err)
})
this.mqClient.on('reconnect', () => {
console.log('重连中......')
})
}
}
export default {
install(app: App, connection: string, opts: MqttConnOpt): void {
if (!connection) {
throw new Error("[mqtt] cannot locate connection");
}
const mqtt = new MQTT(connection, opts);
app.config.globalProperties.$mqtt = mqtt;
const hasProxy = typeof Proxy !== "undefined" && typeof Proxy === "function" && /native code/.test(Proxy.toString());
app.mixin({
created() {
const mqtts = this.$options["mqtts"];
const vm = this;
if (hasProxy) {
this.$options.mqtts = new Proxy(
{},
{
set(target: any, key: any, value: any): boolean {
mqtt.subscribe(key, 0)
Emitter.addListener(key, value, vm);
Reflect.set(target, key, value)
return true;
},
deleteProperty(target: { key: any }, key: any): boolean {
console.log('remove listener--', key)
Emitter.removeListener(key, vm.$options.mqtts[key], vm);
Reflect.deleteProperty(target, key)
return true;
}
}
);
if (mqtts) {
Object.keys(mqtts).forEach((key: string) => {
this.$options.mqtts[key] = mqtts[key];
});
}
}
},
beforeUnmount() {
if (hasProxy) {
const mqtts = this.$options["mqtts"];
if (mqtts) {
Object.keys(mqtts).forEach((key: string) => {
delete this.$options.mqtts[key];
});
}
}
}
})
}
}
3.Emitter
utils/mqtt/Emitter.ts
export class Emitter<T = any> {
private listeners: Map<any, any>;
constructor() {
this.listeners = new Map();
}
addListener(label: T, callback: (...params: T[]) => void, vm: T): boolean {
if (typeof callback === "function") {
this.listeners.has(label) || this.listeners.set(label, []);
this.listeners.get(label).push({ callback: callback, vm: vm });
return true;
}
return false;
}
removeListener(label: T, callback: () => void, vm: T): boolean {
const listeners = this.listeners.get(label);
let index;
if (listeners && listeners.length) {
index = listeners.reduce((i: number, listener: any, index: number) => {
if (
typeof listener.callback === "function" &&
listener.callback === callback &&
listener.vm === vm
) {
i = index;
}
return i;
}, -1);
if (index > -1) {
listeners.splice(index, 1);
this.listeners.set(label, listeners);
return true;
}
}
return false;
}
emit(label: string, ...args: T[]): boolean {
const listeners = this.listeners.get(label);
if (listeners && listeners.length) {
listeners.forEach((listener: { callback: (...params: T[]) => void; vm: T }) => {
listener.callback.apply<any, any, any>(listener.vm, [label, ...args]);
}
);
return true;
}
return false;
}
}
export default new Emitter();