在Vue或React项目中对接MQTT消息通常需要借助MQTT客户端库,这些库允许前端应用与MQTT代理(如Eclipse Mosquitto、EMQX等)进行通信。以下是一个基本的对接流程,适用于Vue和React项目:
1. 选择MQTT客户端库
对于Vue和React项目,常用的MQTT客户端库包括mqtt.js
(适用于浏览器和Node.js环境)和paho-mqtt
(专注于浏览器环境)。
2. 安装MQTT客户端库
在你的Vue或React项目中,你需要安装所选的MQTT客户端库。例如,如果你选择mqtt.js
,你可以使用npm或yarn进行安装:
npm install mqtt --save
# 或者
yarn add mqtt
# 或者
pnpm install mqtt
3. 配置MQTT连接
在你的Vue或React组件中,创建一个MQTT客户端实例,并配置连接参数(如代理URL、端口、客户端ID、用户名和密码等)。
4. 订阅主题和发布消息
使用MQTT客户端实例的subscribe
方法订阅一个或多个主题,以便接收来自这些主题的消息。使用publish
方法向特定主题发布消息。
5. 处理连接和断开事件
监听MQTT连接的成功、失败、断开和重连等事件,以便在必要时采取适当的行动(如重试连接、显示错误消息等)。
6. 在Vue或React组件中使用MQTT
将MQTT客户端实例和相关的订阅、发布逻辑集成到你的Vue或React组件的生命周期方法中。确保在组件销毁时正确断开MQTT连接,以避免内存泄漏或不必要的连接。
全局组件封装
/**
*
* 调用方式如下
* const mqttClient = new MqttClient('mqtt://your-broker-url');
* mqttClient.connect();
* mqttClient.subscribe('your/topic', (topic, message) => {
* console.log(`${topic}: ${message}`);
* });
*
* 在页面销毁时断开连接,释放资源(防止骂娘)
* mqttClient.disconnect();
*
*/
import mqtt from 'mqtt';
// 定义MqttClient类
class MqttClient {
// 构造函数,接收broker的URL和客户端ID(可选)
constructor(brokerUrl, clientId = `client-${Math.random().toString(16).substr(2, 8)}`) {
this.brokerUrl = brokerUrl; // 存储broker的URL
this.clientId = clientId; // 存储客户端ID,如果没有提供则生成一个随机的
this.client = null; // 初始化mqtt客户端为null
}
/**
* 连接到MQTT broker的方法
*/
connect() {
const options = {
clientId: this.clientId, // 设置客户端ID
clean: true, // 设置为true表示在断开连接时清除会话
connectTimeout: 4000, // 设置连接超时时间
reconnectPeriod: 1000, // 设置重连间隔时间
};
this.client = mqtt.connect(this.brokerUrl, options); // 使用mqtt.connect方法连接到broker
/**
* 监听连接事件
*/
this.client.on('connect', () => {
console.log('MQTT connected');
// 可以进行数据订阅todo
});
/**
* 监听错误事件
*/
this.client.on('error', (error) => {
console.error('MQTT error:', error);
});
/**
* 监听关闭事件
*/
this.client.on('close', () => {
console.log('MQTT connection closed');
});
/**
* 监听离线事件
*/
this.client.on('offline', () => {
console.log('MQTT client offline');
});
/**
* 监听重连事件
*/
this.client.on('reconnect', () => {
console.log('MQTT client reconnecting...');
});
}
/**
* 订阅主题的方法,接收主题和回调函数作为参数
* @param {string} topic
* @param {fun} callback
*/
subscribe(topic, callback) {
this.client.subscribe(topic, { qos: 1 }, (error) => { // 使用qos 1保证消息至少被传递一次,2 网络开销较大,不推荐用 0
if (error) {
console.error('Subscribe error:', error);
} else {
console.log(`Subscribed to topic: ${topic}`);
// 监听消息事件,当收到消息时调用回调函数,receivedTopic与订阅主题匹配的主题
this.client.on('message', (receivedTopic, message) => {
callback(receivedTopic, message.toString()); // 调用回调函数处理消息
});
}
});
}
/**
* 发布消息到指定主题的方法,接收主题、消息和qos(可选)作为参数
* @param {string} topic
* @param {string|Buffer} message
* @param {number} qos
*/
publish(topic, message, qos = 1) {
this.client.publish(topic, message, { qos }, (error) => { // 使用指定的qos发布消息
if (error) {
console.error('Publish error:', error);
} else {
console.log(`Published message to topic: ${topic}`);
}
});
}
/**
* 断开与MQTT broker连接的方法
*/
disconnect() {
this.client.end();
// if (this.client.connected) {
// this.client.end(); // 断开连接
// }
}
}
export default MqttClient;
在React中,你可以将类似的逻辑放入一个函数组件或类组件中,并使用React的useEffect
钩子来处理组件的生命周期事件。
组件实例调用
/**
* 以下为mqtt测试代码wss://mqtt.example.com:8443/mqtt
*/
const mqMessage = ref(null)
const mqttClient = new MqttClient('ws://broker.emqx.io:8083/mqtt');
function getMqtt() {
mqttClient.connect();
mqttClient.subscribe('Lora/mdgk001', (topic, message) => {
mqMessage.value = message
});
}
/**
* 手动关闭连接
*/
function closeMqtt() {
if (mqttClient) {
mqttClient.disconnect();
}
}
/**
* 组件销毁时断开mqtt连接,释放资源
*/
onUnmounted(() => {
if (mqttClient) {
mqttClient.disconnect();
}
})
注意事项
- 安全性:确保你的MQTT连接是安全的(使用WSS而不是WS,如果可能的话),并且你的MQTT代理配置了适当的身份验证和授权机制。
- 性能:在前端应用中处理MQTT连接时,要注意性能问题。避免不必要的订阅和发布操作,以及处理大量消息时的性能瓶颈。
- 错误处理:确保你的代码能够妥善处理各种可能的错误情况,如连接失败、订阅失败、消息解析错误等。