更新原生小程序封装(新增缓存订阅)完美解决

javascript 复制代码
import mqtt from '../utils/mqtt.min'

let client = null
let topicCallbacks = {}    // 每个 topic 对应页面回调
let pendingSubscribes = [] // 连接前缓存订阅

const options = {
  protocolVersion: 4,
  clean: true,
  reconnectPeriod: 1000,
  connectTimeout: 30 * 1000,
  resubscribe: true,
  clientId: 'wx_' + Math.random().toString(16).substr(2, 8),
  username: '',
  password: '',
}

const mqttHost = ''

const MQTT = {
  connect() {
    if (client && client.connected) return
    client = mqtt.connect(mqttHost, options)

    client.on('connect', () => {
      console.log('MQTT连接成功')

      // 重连后重新订阅所有 topic
      Object.keys(topicCallbacks).forEach(topic => {
        client.subscribe(topic)
      })

      // 处理连接前缓存的订阅
      pendingSubscribes.forEach(({ topic, callback }) => {
        topicCallbacks[topic] = callback
        client.subscribe(topic)
      })
      pendingSubscribes = []
    })

    client.on('message', (topic, message) => {
      const payload = message.toString()
      // 调用页面回调
      if (topicCallbacks[topic]) topicCallbacks[topic](payload)
    })

    client.on('error', (err) => console.error('MQTT连接失败', err))
    client.on('reconnect', () => console.log('正在重连...'))
    client.on('close', () => console.log('MQTT连接已断开'))
  },

  subscribe(topic, callback) {
    if (!client || !client.connected) {
      console.log('客户端未连接,缓存订阅', topic)
      pendingSubscribes.push({ topic, callback })
      return
    }
    topicCallbacks[topic] = callback
    client.subscribe(topic, { qos: 0 }, (err) => {
      if (!err) console.log(`已订阅:${topic}`)
      else console.error('订阅失败', err)
    })
  },

  unsubscribe(topic) {
    if (!client || !client.connected) return
    client.unsubscribe(topic, () => {
      delete topicCallbacks[topic]
      console.log(`取消订阅:${topic}`)
    })
  },
  publish(topic, message, qos = 0) {
    if (!client || !client.connected) {
      console.error('MQTT未连接,消息发布失败')
      return
    }
    // 保证消息是字符串
    const payload = typeof message === 'string' ? message : JSON.stringify(message)
    client.publish(topic, payload, { qos }, (err) => {
      if (err) console.error(`发布到 ${topic} 失败:`, err)
      else console.log(`消息已发布到 ${topic}:`, payload)
    })
  },
  end() {
    if (client) {
      client.end(true)   // true 表示强制断开,不等待未发送的消息
      client = null
      topicCallbacks = {}
      pendingSubscribes = []
      console.log('MQTT连接已断开')
    }
  },
  isConnected() {
    return !!(client && client.connected)
  },
  // 为兼容旧代码,disconnect 指向 end
  disconnect() {
    this.end()
  }
}

export default MQTT

app.js全局连接,onshow连接,onhide断联

javascript 复制代码
   if (!MQTT.isConnected()) {
      // 需要恢复连接时调用
      MQTT.connect();
    }


  onHide(){
    MQTT.disconnect();
    console.log("全局hide");
  },

页面级别订阅和接受消息

javascript 复制代码
   MQTT.subscribe(`${openIdtoc}`, (payload) => {
      console.log("解析后的数据11111111111111:", payload);
      try {
      
      } catch (err) {
        console.log("消息不是 JSON,原始内容:", payload);
      }
    })
相关推荐
5335ld2 小时前
后端给的post 方法但是要求传表单数据格式(没有{})
开发语言·前端·javascript·vue.js·ecmascript
二川bro2 小时前
第33节:程序化生成与无限地形算法
前端·算法·3d·threejs
QDKuz2 小时前
掌握Vue2转Vue3, Options API 转 Composition API
前端·javascript·vue.js
老前端的功夫2 小时前
前端Echarts性能优化:从卡顿到流畅的百万级数据可视化
前端·javascript
进击的野人2 小时前
深入解析localStorage:前端数据持久化的核心技术
前端·javascript
懵圈2 小时前
第2章:项目启动 - 使用Vite脚手架初始化项目与工程化配置
前端
Mh2 小时前
如何优雅的消除“if...else...”
前端·javascript
火鸟22 小时前
给予虚拟成像台尝鲜版十之二,完善支持 HTML 原型模式
前端·html·原型模式·通用代码生成器·给予虚拟成像台·快速原型·rust语言
逍遥江湖3 小时前
Vue3 + TypeScript 项目框架搭建指南
前端