From 15a5db4479d6ec0647361ad37f1da8016f89bea7 Mon Sep 17 00:00:00 2001 From: lld <15027638633@163.com> Date: Tue, 30 Dec 2025 20:31:47 +0800 Subject: [PATCH] =?UTF-8?q?mqtt=E5=85=A8=E5=B1=80=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 18 ++++++------ utils/mqtt.js | 77 +++++++++++++++++++++++++-------------------------- 2 files changed, 45 insertions(+), 50 deletions(-) diff --git a/App.vue b/App.vue index 5c4d32f..afe3896 100644 --- a/App.vue +++ b/App.vue @@ -19,11 +19,10 @@ keepalive: 60, clean: true }, - globalSubscribeTopic: [ // 全局基础订阅列表(所有页面都需要的主题) + mqttSubscribeList: [ // 全局基础订阅列表(所有页面都需要的主题) {topic: 'dtu/#', qos: 0}, // {topic: 'system/status', qos: 1} ], - mqttStatus: 'disconnected' // 全局连接状态:connected/disconnected/reconnecting }, onLaunch() { this.initApp() @@ -33,18 +32,16 @@ onShow() { console.log('应用切前台,检查MQTT连接'); const { isConnected } = getMQTTStatus(); - if (!isConnected && this.globalData.mqttStatus !== 'disconnected') { - // 非主动断开的情况下,切前台重连 - manualReconnect(this.globalData.mqttConfig); - this.globalData.mqttStatus = 'reconnecting'; + if (!isConnected) { + this.initGlobalMQTT(); } + console.info("mqtt:",isConnected,getMQTTStatus); }, onHide() { console.log('应用切后台,断开MQTT连接'); // 切后台主动断开(避免小程序后台占用资源) disconnectMQTT(); - this.globalData.mqttStatus = 'disconnected'; this.globalData.mqttClient = null; }, methods: { @@ -71,15 +68,16 @@ // 调用工具类初始化连接(传入全局配置+全局订阅列表) const client = await initMQTT( this.globalData.mqttConfig, - this.globalData.globalSubscribeTopic + this.globalData.mqttSubscribeList ); // 挂载客户端到全局 this.globalData.mqttClient = client; - this.globalData.mqttStatus = 'connected'; + // 通知所有页面:客户端已就绪,可绑定自定义事件 + uni.$emit('mqtt_client_ready', client); console.log('全局MQTT初始化成功'); } catch (err) { console.error('全局MQTT初始化失败:', err); - this.globalData.mqttStatus = 'disconnected'; + uni.$emit('mqtt_init_fail', err); } } } diff --git a/utils/mqtt.js b/utils/mqtt.js index dd38b19..be45473 100644 --- a/utils/mqtt.js +++ b/utils/mqtt.js @@ -18,6 +18,7 @@ let isManualDisconnect = false; // 是否主动断开(用于区分主动/被 * 初始化MQTT连接 * @param {Object} config - MQTT连接配置 * @param {Array} subs - 初始订阅列表,格式:[{ topic: 'topic1', qos: 0 }, { topic: 'topic2', qos: 1 }] + * // 初始化连接(移除事件监听,只返回客户端实例) * @returns {Promise} 连接成功/失败的Promise */ export function initMQTT(config, subs = []) { @@ -60,50 +61,42 @@ export function initMQTT(config, subs = []) { // 7. 创建客户端并连接 client = mqtt.connect(connectUrl, mqttOptions); - // 8. 监听连接成功 - client.on('connect', () => { - console.log('MQTT连接成功:', connectUrl); - currentReconnectTimes = 0; // 重置重连次数 - // 9. 订阅初始主题 - subscribeTopics(subscribeList); - resolve(client); - }); + // 仅保留连接成功的基础逻辑(订阅列表),移除其他事件监听 + client.on('connect', () => { + console.log('MQTT连接成功:', connectUrl); + currentReconnectTimes = 0; + // 9. 订阅初始主题 + subscribeTopics(subscribeList); + resolve(client); // 成功后返回客户端实例,让页面自定义监听 + }); - // 10. 监听连接错误 - client.on('error', (err) => { - console.error('MQTT连接错误:', err); - client.end(); - reject(err); - }); - - // 11. 监听连接断开(被动断开则触发重连) - client.on('close', () => { - console.log('MQTT连接已断开'); - client = null; - // 非主动断开 + 未达最大重连次数 → 触发重连 - if (!isManualDisconnect && currentReconnectTimes < maxReconnectTimes) { - reconnectMQTT(config); - } - }); - - // 12. 监听消息(全局消息转发,页面层通过uni.$on监听) - client.on('message', (topic, message) => { - const msg = { - topic, - payload: message.toString(), // 转字符串(原始是Buffer) - timestamp: Date.now() - }; - // 全局广播消息,页面层按需监听 - uni.$emit('mqtt_message', msg); - }); - - } catch (err) { - console.error('MQTT初始化失败:', err); - reject(err); + // 移除工具层的error/close/message监听 → 交给页面处理 + // 保留重连的核心逻辑(通过单独的close监听,仅用于重连,不处理业务) + client.on('close', () => { + console.log('MQTT连接已断开(工具层)'); + const oldClient = client; // 暂存旧客户端,避免重连时被覆盖 + client = null; + if (!isManualDisconnect && currentReconnectTimes < maxReconnectTimes) { + reconnectMQTT(config).then(newClient => { + // 重连成功后,全局通知页面:客户端已更换,需重新绑定事件 + uni.$emit('mqtt_reconnected', newClient); + }).catch(err => { + uni.$emit('mqtt_reconnect_fail', err); + }); } - }); + // 通知页面:旧客户端已断开 + uni.$emit('mqtt_closed', oldClient); + }); + + } catch (err) { + console.error('MQTT初始化失败:', err); + reject(err); + } + }); } +// 其他方法(subscribeTopics/unsubscribeTopics/publishMQTT/disconnectMQTT/reconnectMQTT/getMQTTStatus/manualReconnect) +// 【完全不变】,直接复用之前的代码 /** * 订阅主题(支持单个/多个) * @param {Array} topics - 订阅列表,格式:[{ topic: 'topic1', qos: 0 }, { topic: 'topic2', qos: 1 }] @@ -257,4 +250,8 @@ export function getMQTTStatus() { export function manualReconnect(config) { currentReconnectTimes = 0; // 重置重连次数 reconnectMQTT(config); +} + +export function getMQTTClientInstance() { + return client; } \ No newline at end of file