diff --git a/App.vue b/App.vue index 3bf6e6e..c979bc4 100644 --- a/App.vue +++ b/App.vue @@ -13,6 +13,13 @@ export default { } }, onLaunch: function() { + // #ifdef H5 + // 监听H5页面刷新/关闭事件 + window.addEventListener('beforeunload', () => { + mqttUtil.disconnectMqtt() + console.log('H5刷新,强制断开MQTT连接') + }) + // #endif this.initApp() mqttUtil.disconnectMqtt() @@ -21,12 +28,21 @@ export default { if (savedSubscribeList && savedSubscribeList.length > 0) { this.globalData.mqtt.subscribeList = savedSubscribeList } + // ========== 新增:被踢下线断开mqtt ========== + + + // 2. 监听token过期事件(全局事件) + uni.$on('tokenExpired', () => { + console.info("被动token校验") + this.handleTokenExpired() + }) }, onShow() { + // 重新进入后执行 console.log('小程序切前台/首次显示') const token = getToken() || this.globalData.mqtt.token if (token) { - console.info("token存在,mqtt重新连接中。。") + // 兜底检查:如果globalData里没有列表,但缓存里有,补充恢复 if (this.globalData.mqtt.subscribeList.length === 0) { const savedSubscribeList = uni.getStorageSync('mqtt_subscribe_list') @@ -34,7 +50,11 @@ export default { this.globalData.mqtt.subscribeList = savedSubscribeList } } - this.reconnectMqtt() + console.info("clientaasa: ",mqttUtil.getMqttState().client) + if (mqttUtil.getMqttState().client==null) { + console.info("token存在,mqtt重新连接中。。") + this.reconnectMqtt() + } } }, onHide() { @@ -110,6 +130,36 @@ export default { // ========== 新增:登出时清空localStorage的订阅列表 ========== uni.removeStorageSync('mqtt_subscribe_list') console.log('登出成功,MQTT已断开') + }, + + + + // token过期处理逻辑(核心) + handleTokenExpired() { + + console.info("被踢下线") + // 1. 断开MQTT连接 + mqttUtil.disconnectMqtt() + + // 2. 清除token和用户信息 + this.globalData.mqtt = { + hasLogin: false, + token: '', + subscribeList: [] + } + + // 3. 提示用户并跳转登录页 + uni.showModal({ + title: '提示', + content: '登录已过期,请重新登录', + showCancel: false, + success: () => { + // 跳转登录页(关闭所有页面,避免返回) + uni.reLaunch({ + url: '/pages/login' + }) + } + }) } } } diff --git a/config.js b/config.js index 8961a79..f92f2ca 100644 --- a/config.js +++ b/config.js @@ -1,6 +1,6 @@ // 应用全局配置 module.exports = { - baseUrl: process.env.NODE_ENV === "production" ? "/api" : "http://localhost:8088", + baseUrl: process.env.UNI_PLATFORM === 'mp-weixin'?"http://122.51.109.52:8088":'http://localhost:8088', // 应用信息 appInfo: { // 应用名称 diff --git a/manifest.json b/manifest.json index 51ab1e1..54998f7 100644 --- a/manifest.json +++ b/manifest.json @@ -51,6 +51,10 @@ "optimization" : { "subPackages" : true }, + "networkTimeout": { + "request": 60000, + "connectSocket": 60000 + }, "usingComponents" : true }, "vueVersion" : "2", @@ -65,6 +69,12 @@ "router" : { "mode" : "hash", "base" : "/m/" + }, + "optimization" : { + "minimize" : true, + "treeShaking" : { + "enable" : true + } } } } diff --git a/static/logo.png b/static/logo.png index e8a0ac2..0889b6a 100644 Binary files a/static/logo.png and b/static/logo.png differ diff --git a/static/logo200.png b/static/logo200.png index 9482050..89a231a 100644 Binary files a/static/logo200.png and b/static/logo200.png differ diff --git a/utils/mqtt.js b/utils/mqtt.js index ecea5d6..09c759a 100644 --- a/utils/mqtt.js +++ b/utils/mqtt.js @@ -7,20 +7,21 @@ */ // 引入小程序版MQTT核心库(确保mqtt.min.js在utils目录) -import mqtt from './mqtt.min.js' + +// 微信小程序端:引入适配小程序的 mqtt 版本 +import mqtt from 'mqtt/dist/mqtt' // ===================== MQTT配置(暂时写死,TODO:后续从数据字典获取)===================== const MQTT_CONFIG = { - server: 'ws://122.51.109.52:9001/mqtt', // 替换为你的MQTT服务器地址 + server: 'wxs://mq.mj142.cn:443/mqtt', // 替换为你的MQTT服务器地址 username: 'admin', // 替换为通用账号 password: 'Admin#12345678', // 替换为通用密码 clean: true, - host: '122.51.109.52', - port: 9001, + host: 'mq.mj142.cn', + port: 443, reconnectPeriod: 5000, // 重连间隔 connectTimeout: 10000, // 连接超时 keepalive: 60, // 心跳时间 - protocol: 'ws' } // ===================== MQTT全局状态管理 ===================== @@ -40,6 +41,15 @@ const mqttState = { * @returns {Boolean} - 是否配置成功 */ export function initMqttConfig() { + if (mqttState.client) { + console.info("重连前强制断开",mqttState.options.clientId) + // 加try-catch,避免断开时客户端已异常导致报错 + try { + mqttState.client.end(true) + } catch (err) { + console.warn('旧连接断开失败:', err) + } + } try { // 仅随机生成clientId(保证唯一性,避免连接冲突) mqttState.options.clientId = `wx_mqtt_${Math.random().toString(16).substr(2, 10)}` @@ -66,30 +76,24 @@ export function connectMqtt() { console.error('MQTT连接失败:请先调用initMqttConfig初始化配置') return false } + console.info(mqttState.client!=null,mqttState.client) // 避免重复连接 - if (mqttState.isConnected && mqttState.client) { + if (mqttState.client!=null) { console.log('MQTT已连接,无需重复操作') return true } try { // 创建客户端实例(同步操作) - // mqttState.client = mqtt.connect(MQTT_CONFIG.server, mqttState.options) - // #ifdef MP-WEIXIN - MQTT_CONFIG.protocol = 'wxs'; + // #ifndef MP-WEIXIN + MQTT_CONFIG.server = 'wss://mq.mj142.cn:443/mqtt' // #endif - mqttState.client = mqtt.connect({ - host: MQTT_CONFIG.host, - port: MQTT_CONFIG.port, - clientId: mqttState.options.clientId, - username: MQTT_CONFIG.username, - password: MQTT_CONFIG.password, - // 关键:指定用小程序的Socket - protocol: MQTT_CONFIG.protocol // 或'ws',根据你的MQTT服务协议 - }) + console.info("mqttState.connect",mqttState) + mqttState.client = mqtt.connect(MQTT_CONFIG.server, mqttState.options) + console.info("重连中。。") // 监听核心事件(异步,同步更新状态) mqttState.client.on('connect', () => { - console.log('MQTT连接成功') + console.log('MQTT连接成功',mqttState.options.clientId) mqttState.isConnected = true // 连接成功后自动订阅全局列表 subscribeAllTopics() @@ -266,7 +270,8 @@ export function getMqttState() { return { isConnected: mqttState.isConnected, subscribeList: [...mqttState.subscribeList], - clientId: mqttState.options.clientId + clientId: mqttState.options.clientId, + client: mqttState.client } } diff --git a/utils/request.js b/utils/request.js index 6d044d4..58b98f8 100644 --- a/utils/request.js +++ b/utils/request.js @@ -38,6 +38,7 @@ const request = config => { const code = res.data.code || 200 const msg = errorCode[code] || res.data.msg || errorCode['default'] if (code === 401) { + uni.$emit('tokenExpired') store.dispatch('LogOut').then(res => { uni.reLaunch({ url: '/pages/login' }) })