mqtt.js 客户端封装
没封装前使用
js
const client = mqtt.connect('ws://10.10.20.9:9001')
onMounted(() => {
const topicList = []
const channelCount = 12
for(let i = 0; i < channelCount; i++) {
topicList.push(`/test/sendImage${i + 1}`)
}
client.on('connect', () => {
console.log('connected')
topicList.forEach((topic) => {
client.subscribe(topic)
})
client.on('message', (topic, message) => {
// 主要差别在这里,需要判断 topic 是当前订阅的,才进行处理,
// 每次需要遍历所有的 topic
topicList.forEach((t, index) => {
if(topic === t) {
handleImage(message, index)
}
})
})
})
client.on('error', (error) => {
console.error('mqtt connect error', error)
})
})
onUnmounted(() => {
client.end()
})
封装后使用
js
const client = new Mqtt()
client.connect('ws://10.10.20.9:9001')
onMounted(() => {
const topicList = []
const channelCount = 12
for(let i = 0; i < channelCount; i++) {
topicList.push(`/test/sendImage${i + 1}`)
}
topicList.forEach((topic, index) => {
// 订阅topic时,注册 callback,
// 当前topic接收到的数据在 callback 中处理
client.subscribe(topic, (message) => {
handleImage(message, index)
})
})
})
onUnmounted(() => {
client.disconnect()
})
封装 Mqtt class
原理是 subscribe 时,注册当前topic处理的 callback,在callback中处理接收到的数据
ts
import mqtt, { IClientOptions, MqttClient } from 'mqtt';
export class Mqtt {
private client: MqttClient | null = null;
/**
* 连接到 MQTT 服务器
* @param brokerUrl
* string: MQTT 服务器地址,
* IClientOptions: 客户端配置
* @param opts
* @returns
*/
connect(brokerUrl: string): MqttClient
connect(opts: IClientOptions): MqttClient
connect(brokerUrl: string, opts?: IClientOptions): MqttClient
connect(
brokerUrl: string | IClientOptions,
opts?: IClientOptions,
): MqttClient {
if(this.client) {
console.warn('MQTT client is already connected.');
return
}
// 如果第一个参数是 IClientOptions 类型,则将其赋值给 opts
if(typeof brokerUrl === 'object') {
opts = brokerUrl;
brokerUrl = ''; // 如果 brokerUrl 是空字符串,mqtt.connect 会使用 opts 中的 brokerUrl
}
// 确保 opts 不为空
opts = opts || {};
// 调用 mqtt.connect
this.client = mqtt.connect(brokerUrl, opts);
this.client.on('connect', () => {
console.log('Connected to MQTT broker');
})
this.client.on('error', (error) => {
console.error('MQTT error:', error);
});
this.client.on('close', () => {
console.log('Disconnected from MQTT broker');
});
return this.client;
}
/**
* 订阅主题
* @param topic 主题
* @param callback 消息回调函数
*/
subscribe(topic: string, callback: (message: any) => void): void {
if(!this.client) {
console.error('MQTT client is not connected.');
return;
}
this.client.subscribe(topic, (err) => {
if(err) {
console.error('Subscription error:', err);
} else {
console.log(`Subscribed to topic: ${topic}`);
}
});
this.client.on('message', (receivedTopic, message) => {
if(receivedTopic === topic) {
callback(message);
}
})
}
/**
* 发布消息到主题
* @param topic 主题
* @param message 消息内容
*/
ppublish(topic: string, message: any) {
if(!this.client) {
console.error('MQTT client is not connected.');
return;
}
this.client.publish(topic, message, (err) => {
if(err) {
console.error('Publish error:', err);
} else {
console.log(`Message published to topic: ${topic}`);
}
})
}
/**
* 断开连接
*/
disconnect() {
if(this.client) {
this.client.end();
this.client = null;
}
}
}
结语:
以上是对 mqtt.js 的简单业务封装。当然还有其他的封装方式,只需要满足当前的业务需求即可。