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

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);
      }
    })
相关推荐
机灵猫2 分钟前
Redis 内部机制:持久化、内存淘汰与延迟优化
数据库·redis·缓存
YAY_tyy2 分钟前
数据处理:要素裁剪、合并与简化
前端·arcgis·turfjs
LYFlied12 分钟前
【每日算法】LeetCode 62. 不同路径(多维动态规划)
前端·数据结构·算法·leetcode·动态规划
console.log('npc')29 分钟前
vue3文件上传弹窗,图片pdf,word,结合预览kkview
前端·javascript·vue.js·pdf·word
inferno35 分钟前
CSS 基础(第二部分)
前端·css
BD_Marathon38 分钟前
Router_路由传参
前端·javascript·vue.js
快乐的划水a43 分钟前
「CIC→DMA→FIFO」的完整数据流程
缓存
闲云一鹤1 小时前
Cesium 去掉默认瓦片和地形,解决网络不好时地图加载缓慢的问题
前端·cesium
Dreamcatcher_AC1 小时前
前端面试高频13问
前端·javascript·vue.js
AI陪跑1 小时前
深入剖析:GrapesJS 中 addStyle() 导致拖放失效的问题
前端·javascript·react.js