import * as mqtt from 'mqtt/dist/mqtt.min.js'
import { WSS_URL } from '@/constant'
function falseFn() {
return false
}
export default class MQTT {
constructor() {
this.connected = false
this.instance = null
this.routers = {}
}
static getInstance() {
if (!this.instance) {
this.instance = new MQTT()
}
return this.instance
}
connect() {
return new Promise((resolve, reject) => {
this.client = mqtt.connect(WSS_URL, {
clean: true,
clientId: 'mqtt-test' + Math.random(),
connectTimeout: 30 * 1000,
keepalive: 60,
protocolVersion: 5,
reconnectPeriod: 2000,
reschedulePings: true,
resubscribe: true,
})
this.client.on('connect', () => {
this.connected = true
this.client.on('message', (t, m) => {
if (this.routers[t]) {
for (let i = 0; i < this.routers[t].length; i++) {
this.routers[t][i](m)
}
}
})
console.log('连接成功')
resolve(this)
})
this.client.on('error', err => {
console.log('连接失败')
reject(err)
})
})
}
subscribe(topic, config = {}) {
if (this.connected) {
this.client.subscribe(topic, config, () => {
console.log(`订阅成功:${topic}`)
})
}
return this
}
unsubscribe(topic, config = {}) {
this.client.unsubscribe(topic, config, () => {
console.log(`取消订阅:${topic}`)
})
}
publish(topic, message) {
console.log(`发布消息:${topic} -> `)
console.log(message)
this.client.publish(topic, message, { qos: 1 })
}
handle(callback) {
if (!this.client._events.message) {
this.client.on('message', callback)
}
}
addRouter(topic, callback) {
if (!this.routers[topic]) {
this.routers[topic] = []
}
this.routers[topic].push(callback)
return callback
}
addRouterViaJSON(topic, callback) {
if (!this.routers[topic]) {
this.routers[topic] = []
}
const func = msg => {
try {
const obj = JSON.parse(msg.toString())
callback(obj)
} catch (e) {
callback(null)
}
}
this.routers[topic].push(func)
return func
}
delRouter(topic, fn) {
if (!this.routers[topic]) {
return
}
if (fn) {
for (let i = 0; i < this.routers[topic].length; i++) {
if (this.routers[topic][i] === fn) {
this.routers[topic][i] = falseFn
}
}
} else {
delete this.routers[topic]
}
}
end() {
console.log('关闭连接成功')
this.client.end()
}
}