找回密码
 立即注册
首页 业界区 业界 MQTT状态管理Vuex全局状态管理

MQTT状态管理Vuex全局状态管理

凶契帽 昨天 00:40
1.uniapp集成MQTT协议,参考我的文章:https://www.cnblogs.com/zhangyouwu/p/19439905
2.创建store/index.js
  1. // 页面路径:store/index.js
  2. import { createStore } from 'vuex'
  3. const store = createStore({
  4.     state:{//存放状态
  5.         "xcx_zt":0,//程序是否在线
  6.         "m_zt":0,//设备是否在线
  7.         'm_id':'',//设备ID
  8.     },
  9.     mutations: {
  10.         chang_xcx_zt(state, n) {
  11.             state.xcx_zt = n
  12.         },
  13.         chang_m_zt(state, n) {
  14.             state.m_zt = n
  15.         },
  16.         chang_m_id(state, n) {
  17.             state.m_id = n
  18.         },
  19.     }
  20. })
  21. export default store
复制代码
3.在 main.js 中导入文件,主要这2句
1.png

 
  1. import store from './store'
复制代码
  1. app.use(store)
复制代码
 4.修改mqtt.js
2.gif
3.gif
  1. import mqtt from 'mqtt/dist/mqtt.min'
  2. import store from '@/store/index.js'
  3. // MQTT 配置(根据实际服务端修改)
  4. const MQTT_CONFIG = {
  5.     // 不同端的连接协议:
  6.     // H5: ws://xxx:8083/mqtt 或 wss://xxx:8084/mqtt
  7.     // 微信小程序: wxs://xxx:8084/mqtt(需配置域名白名单)
  8.     // App: tcp://xxx:1883(需配置网络权限)
  9.     host: 'wxs://xxx:8084/mqtt',
  10.     // host: 'ws://xxx:8083/mqtt',
  11.     clientId: `wine-${Math.random().toString(16).substr(2, 8)}`, // 唯一客户端ID
  12.     username: 'zyw', // 服务端认证用户名(无则留空)
  13.     password: 'zyw123456', // 服务端认证密码(无则留空)
  14.     keepalive: 60, // 心跳间隔(秒)
  15.     reconnectPeriod: 5000, // 重连间隔(毫秒)
  16.     clean: true // 清除会话(true:断开后不保留订阅)
  17. }
  18. // 全局 MQTT 客户端实例
  19. let client = null
  20. // 消息回调函数(供页面监听)
  21. let messageCallback = null
  22. /**
  23. * 连接 MQTT 服务器
  24. * @param {Function} callback 消息接收回调 (topic, message) => {}
  25. */
  26. export function connectMQTT(callback) {
  27.     // 保存消息回调
  28.     messageCallback = callback
  29.     // 已连接则直接返回
  30.     if (client && client.connected){
  31.         store.commit('chang_xcx_zt', 1)//在线
  32.         return false;
  33.     }
  34.     // 创建连接
  35.     client = mqtt.connect(MQTT_CONFIG.host, {
  36.         clientId: MQTT_CONFIG.clientId,
  37.         username: MQTT_CONFIG.username,
  38.         password: MQTT_CONFIG.password,
  39.         keepalive: MQTT_CONFIG.keepalive,
  40.         reconnectPeriod: MQTT_CONFIG.reconnectPeriod,
  41.         clean: MQTT_CONFIG.clean
  42.     })
  43.     // 连接成功回调
  44.     client.on('connect', () => {
  45.         console.log('MQTT 连接成功:', MQTT_CONFIG.clientId);
  46.         if(MQTT_CONFIG.clientId){
  47.             store.commit('chang_xcx_zt', 1)//在线
  48.             if (messageCallback) {
  49.                 var p_obj={};
  50.                 var p_data={};
  51.                
  52.                 p_data.keyword="connect";
  53.                 p_data.clientId=MQTT_CONFIG.clientId;
  54.                 p_data.msg="MQTT 连接成功";
  55.                
  56.                 p_obj.code=1;
  57.                 p_obj.data=p_data;
  58.                 messageCallback(p_obj) // 转字符串便于处理
  59.             }
  60.         }
  61.     })
  62.     // 接收消息回调
  63.     client.on('message', (topic, message) => {
  64.         console.log(`收到消息1:topic=${topic}, message=${message.toString()}`)
  65.         if (messageCallback) {
  66.             messageCallback(topic, message.toString()) // 转字符串便于处理
  67.         }
  68.     })
  69.     // 连接错误回调
  70.     client.on('error', (error) => {
  71.         console.error('MQTT 连接错误:', error)
  72.         store.commit('chang_xcx_zt', 0)//离线
  73.         if (messageCallback) {
  74.             var p_obj={};
  75.             var p_data={};
  76.             p_data.keyword="error";
  77.             p_data.error=error;
  78.             p_data.msg="MQTT 连接错误";
  79.             
  80.             p_obj.code=1;
  81.             p_obj.data=p_data;
  82.             messageCallback(p_obj) // 转字符串便于处理
  83.         }
  84.         
  85.     })
  86.     // 断开连接回调
  87.     client.on('close', () => {
  88.         console.log('MQTT 连接断开');
  89.         store.commit('chang_xcx_zt', 0)//离线
  90.         if (messageCallback) {
  91.             var p_obj={};
  92.             var p_data={};
  93.             p_data.keyword="close";
  94.             p_data.msg="MQTT 连接断开";
  95.             
  96.             p_obj.code=1;
  97.             p_obj.data=p_data;
  98.             messageCallback(p_obj) // 转字符串便于处理
  99.         }
  100.     })
  101.     // 重连回调
  102.     client.on('reconnect', () => {
  103.         console.log('MQTT 正在重连...')
  104.         store.commit('chang_xcx_zt', 0)//离线
  105.         if (messageCallback) {
  106.             var p_obj={};
  107.             var p_data={};
  108.             p_data.keyword="reconnect";
  109.             p_data.msg="MQTT 正在重连";
  110.             
  111.             p_obj.code=1;
  112.             p_obj.data=p_data;
  113.             messageCallback(p_obj) // 转字符串便于处理
  114.         }
  115.     })
  116. }
  117. /**
  118. * 断开 MQTT 连接
  119. */
  120. export function disconnectMQTT(callback) {
  121.     if (client && client.connected) {
  122.         // 保存消息回调
  123.         messageCallback = callback
  124.         client.end()
  125.         client = null
  126.         console.log('MQTT 主动断开连接')
  127.         store.commit('chang_xcx_zt', 0)//离线
  128.         if (messageCallback) {
  129.             var p_obj={};
  130.             var p_data={};
  131.             p_data.keyword="disconnect";
  132.             p_data.msg="MQTT 主动断开连接";
  133.             
  134.             p_obj.code=1;
  135.             p_obj.data=p_data;
  136.             messageCallback(p_obj) // 转字符串便于处理
  137.         }
  138.         
  139.     }
  140. }
  141. /**
  142. * 订阅 MQTT 主题
  143. * @param {String|Array} topic 主题(单个字符串或数组)
  144. * @param {Number} qos 服务质量(0/1/2,默认0)
  145. */
  146. export function subscribeMQTT(topic, qos = 0) {
  147.   if (!client || !client.connected) {
  148.     console.error('MQTT 未连接,无法订阅')
  149.     return
  150.   }
  151.   client.subscribe(topic, { qos }, (error) => {
  152.     if (error) {
  153.       console.error(`订阅主题 ${topic} 失败:`, error)
  154.     } else {
  155.       console.log(`订阅主题 ${topic} 成功`)
  156.     }
  157.   })
  158. }
  159. /**
  160. * 发布 MQTT 消息
  161. * @param {String} topic 主题
  162. * @param {String|Object} message 消息内容(对象会转为JSON字符串)
  163. * @param {Number} qos 服务质量(0/1/2,默认0)
  164. */
  165. export function publishMQTT(topic, message, qos = 0) {
  166.   if (!client || !client.connected) {
  167.     console.error('MQTT 未连接,无法发布消息')
  168.     return
  169.   }
  170.   // 统一转为字符串
  171.   const msg = typeof message === 'object' ? JSON.stringify(message) : message
  172.   client.publish(topic, msg, { qos }, (error) => {
  173.     if (error) {
  174.       console.error(`发布消息到 ${topic} 失败:`, error)
  175.     } else {
  176.       console.log(`发布消息到 ${topic} 成功:`, msg)
  177.     }
  178.   })
  179. }
  180. /**
  181. * 取消订阅 MQTT 主题
  182. * @param {String|Array} topic 主题(单个字符串或数组)
  183. */
  184. export function unsubscribeMQTT(topic) {
  185.   if (!client || !client.connected) {
  186.     console.error('MQTT 未连接,无法取消订阅')
  187.     return
  188.   }
  189.   client.unsubscribe(topic, (error) => {
  190.     if (error) {
  191.       console.error(`取消订阅 ${topic} 失败:`, error)
  192.     } else {
  193.       console.log(`取消订阅 ${topic} 成功`)
  194.     }
  195.   })
  196. }
  197. mqtt.js
复制代码
mqtt.js5.创建在线组件/components/online/online.vue,其中2个getApp().add_log方法是上传连接日志到服务器,请自行删除
4.gif
5.gif
  1. <template>
  2.     <view>
  3.         <view class="topfixed">
  4.             <view class="topfixed_content">
  5.                
  6.                 <view class="topNavBox">
  7.                     <view class="leftBtnBox">
  8.                         <view class="gobackBox color-white font-28">
  9.                             <view>设备:</view>
  10.                             <block v-if="m_zt==1">
  11.                                 <view class="flex">
  12.                                     <u-icon name="pause-circle-fill" color="#00AA59" size="18"></u-icon>
  13.                                     <view class="ml6">在线</view>
  14.                                 </view>
  15.                             </block>
  16.                            
  17.                             <block v-else>
  18.                                 <view class="flex">
  19.                                     <u-icon name="minus-circle-fill" color="#ff0000" size="18"></u-icon>
  20.                                     <view class="ml6">离线</view>
  21.                                 </view>
  22.                             </block>
  23.                         </view>
  24.                         
  25.                     </view>
  26.                 </view>
  27.                
  28.                 <view class="topNavBox">
  29.                     <view class="leftBtnBox">
  30.                         <view class="gobackBox color-white font-28">
  31.                             <view>程序:</view>
  32.                             <block v-if="xcx_zt==1">
  33.                                 <view class="flex" @click="disconnect">
  34.                                     <u-icon name="pause-circle-fill" color="#00AA59" size="18"></u-icon>
  35.                                     <view class="ml6">在线</view>
  36.                                 </view>
  37.                             </block>
  38.                            
  39.                             <block v-else>
  40.                                 <view class="flex" @click="connect">
  41.                                     <u-icon name="minus-circle-fill" color="#ff0000" size="18"></u-icon>
  42.                                     <view class="ml6">离线</view>
  43.                                 </view>
  44.                             </block>
  45.                         </view>
  46.                         
  47.                     </view>
  48.                 </view>
  49.             </view>
  50.         </view>
  51.     </view>
  52. </template>
复制代码
online.vue6.App.vue内容,其中add_log方法是上传连接日志到服务器,请自行删除
  1. [/code] 
  2. 7.创建测试文件/pages/index/index.vue,其中tabBar是我自定义的菜单组件,请自行删除
  3. [align=center] 6.gif [/align][align=center] 7.gif [/align][code]<template>
  4.     <view class="">
  5.         <view>
  6.             <online></online>
  7.         </view>
  8.         <map style="width: 100%; height: 300px;" :latitude="latitude" :longitude="longitude" :style="'height:'+windowHeight*2+'rpx;'">
  9.             
  10.         </map>
  11.         
  12.         <view>
  13.             <tabBar :pageIndex="100" :textType="1" @toTab="toTab"></tabBar>
  14.         </view>
  15.     </view>
  16. </template>
复制代码
index.vue结果
8.png

 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册