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

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);
      }
    })
相关推荐
niucloud-admin37 分钟前
web 端前端
前端
Mr__Miss1 小时前
Redis的持久化
数据库·redis·缓存
2501_916008892 小时前
iOS 上架需要哪些准备,账号、Bundle ID、证书、描述文件、安装测试及上传
android·ios·小程序·https·uni-app·iphone·webview
胖者是谁4 小时前
EasyPlayerPro的使用方法
前端·javascript·css
EndingCoder4 小时前
索引类型和 keyof 操作符
linux·运维·前端·javascript·ubuntu·typescript
liux35284 小时前
Web集群管理实战指南:从架构到运维
运维·前端·架构
沛沛老爹4 小时前
Web转AI架构篇 Agent Skills vs MCP:工具箱与标准接口的本质区别
java·开发语言·前端·人工智能·架构·企业开发
小光学长5 小时前
基于Web的长江游轮公共服务系统j225o57w(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库
Joe5566 小时前
vue2 + antDesign 下拉框限制只能选择2个
服务器·前端·javascript
ChangYan.6 小时前
monorepo 多包管理识别不到新增模块,解决办法
前端·chrome