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

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);
      }
    })
相关推荐
2501_9445255421 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
2601_9498574321 小时前
Flutter for OpenHarmony Web开发助手App实战:快捷键参考
前端·flutter
wangdaoyin201021 小时前
若依vue2前后端分离集成flowable
开发语言·前端·javascript
踩坑小念1 天前
秒杀场景下如何处理redis扣除状态不一致问题
数据库·redis·分布式·缓存·秒杀
心柠1 天前
vue3相关知识总结
前端·javascript·vue.js
Amumu121381 天前
Vue Router(二)
java·前端
a1117761 天前
图书借阅管理系统(FastAPI + Vue)
前端·vue.js·fastapi
常年游走在bug的边缘1 天前
掌握JavaScript作用域:从函数作用域到块级作用域的演进与实践
开发语言·前端·javascript
极致♀雨1 天前
vue2+elementUI table表格勾选行冻结/置顶
前端·javascript·vue.js·elementui
林shir1 天前
3-15-前端Web实战(Vue工程化+ElementPlus)
前端·javascript·vue.js