1.uniapp集成MQTT协议,参考我的文章:https://www.cnblogs.com/zhangyouwu/p/19439905
2.创建store/index.js- // 页面路径:store/index.js
- import { createStore } from 'vuex'
- const store = createStore({
- state:{//存放状态
- "xcx_zt":0,//程序是否在线
- "m_zt":0,//设备是否在线
- 'm_id':'',//设备ID
- },
- mutations: {
- chang_xcx_zt(state, n) {
- state.xcx_zt = n
- },
- chang_m_zt(state, n) {
- state.m_zt = n
- },
- chang_m_id(state, n) {
- state.m_id = n
- },
- }
- })
- export default store
复制代码 3.在 main.js 中导入文件,主要这2句
- import store from './store'
复制代码 4.修改mqtt.js
- import mqtt from 'mqtt/dist/mqtt.min'
- import store from '@/store/index.js'
- // MQTT 配置(根据实际服务端修改)
- const MQTT_CONFIG = {
- // 不同端的连接协议:
- // H5: ws://xxx:8083/mqtt 或 wss://xxx:8084/mqtt
- // 微信小程序: wxs://xxx:8084/mqtt(需配置域名白名单)
- // App: tcp://xxx:1883(需配置网络权限)
- host: 'wxs://xxx:8084/mqtt',
- // host: 'ws://xxx:8083/mqtt',
- clientId: `wine-${Math.random().toString(16).substr(2, 8)}`, // 唯一客户端ID
- username: 'zyw', // 服务端认证用户名(无则留空)
- password: 'zyw123456', // 服务端认证密码(无则留空)
- keepalive: 60, // 心跳间隔(秒)
- reconnectPeriod: 5000, // 重连间隔(毫秒)
- clean: true // 清除会话(true:断开后不保留订阅)
- }
- // 全局 MQTT 客户端实例
- let client = null
- // 消息回调函数(供页面监听)
- let messageCallback = null
- /**
- * 连接 MQTT 服务器
- * @param {Function} callback 消息接收回调 (topic, message) => {}
- */
- export function connectMQTT(callback) {
- // 保存消息回调
- messageCallback = callback
- // 已连接则直接返回
- if (client && client.connected){
- store.commit('chang_xcx_zt', 1)//在线
- return false;
- }
- // 创建连接
- client = mqtt.connect(MQTT_CONFIG.host, {
- clientId: MQTT_CONFIG.clientId,
- username: MQTT_CONFIG.username,
- password: MQTT_CONFIG.password,
- keepalive: MQTT_CONFIG.keepalive,
- reconnectPeriod: MQTT_CONFIG.reconnectPeriod,
- clean: MQTT_CONFIG.clean
- })
- // 连接成功回调
- client.on('connect', () => {
- console.log('MQTT 连接成功:', MQTT_CONFIG.clientId);
- if(MQTT_CONFIG.clientId){
- store.commit('chang_xcx_zt', 1)//在线
- if (messageCallback) {
- var p_obj={};
- var p_data={};
-
- p_data.keyword="connect";
- p_data.clientId=MQTT_CONFIG.clientId;
- p_data.msg="MQTT 连接成功";
-
- p_obj.code=1;
- p_obj.data=p_data;
- messageCallback(p_obj) // 转字符串便于处理
- }
- }
- })
- // 接收消息回调
- client.on('message', (topic, message) => {
- console.log(`收到消息1:topic=${topic}, message=${message.toString()}`)
- if (messageCallback) {
- messageCallback(topic, message.toString()) // 转字符串便于处理
- }
- })
- // 连接错误回调
- client.on('error', (error) => {
- console.error('MQTT 连接错误:', error)
- store.commit('chang_xcx_zt', 0)//离线
- if (messageCallback) {
- var p_obj={};
- var p_data={};
- p_data.keyword="error";
- p_data.error=error;
- p_data.msg="MQTT 连接错误";
-
- p_obj.code=1;
- p_obj.data=p_data;
- messageCallback(p_obj) // 转字符串便于处理
- }
-
- })
- // 断开连接回调
- client.on('close', () => {
- console.log('MQTT 连接断开');
- store.commit('chang_xcx_zt', 0)//离线
- if (messageCallback) {
- var p_obj={};
- var p_data={};
- p_data.keyword="close";
- p_data.msg="MQTT 连接断开";
-
- p_obj.code=1;
- p_obj.data=p_data;
- messageCallback(p_obj) // 转字符串便于处理
- }
- })
- // 重连回调
- client.on('reconnect', () => {
- console.log('MQTT 正在重连...')
- store.commit('chang_xcx_zt', 0)//离线
- if (messageCallback) {
- var p_obj={};
- var p_data={};
- p_data.keyword="reconnect";
- p_data.msg="MQTT 正在重连";
-
- p_obj.code=1;
- p_obj.data=p_data;
- messageCallback(p_obj) // 转字符串便于处理
- }
- })
- }
- /**
- * 断开 MQTT 连接
- */
- export function disconnectMQTT(callback) {
- if (client && client.connected) {
- // 保存消息回调
- messageCallback = callback
- client.end()
- client = null
- console.log('MQTT 主动断开连接')
- store.commit('chang_xcx_zt', 0)//离线
- if (messageCallback) {
- var p_obj={};
- var p_data={};
- p_data.keyword="disconnect";
- p_data.msg="MQTT 主动断开连接";
-
- p_obj.code=1;
- p_obj.data=p_data;
- messageCallback(p_obj) // 转字符串便于处理
- }
-
- }
- }
- /**
- * 订阅 MQTT 主题
- * @param {String|Array} topic 主题(单个字符串或数组)
- * @param {Number} qos 服务质量(0/1/2,默认0)
- */
- export function subscribeMQTT(topic, qos = 0) {
- if (!client || !client.connected) {
- console.error('MQTT 未连接,无法订阅')
- return
- }
- client.subscribe(topic, { qos }, (error) => {
- if (error) {
- console.error(`订阅主题 ${topic} 失败:`, error)
- } else {
- console.log(`订阅主题 ${topic} 成功`)
- }
- })
- }
- /**
- * 发布 MQTT 消息
- * @param {String} topic 主题
- * @param {String|Object} message 消息内容(对象会转为JSON字符串)
- * @param {Number} qos 服务质量(0/1/2,默认0)
- */
- export function publishMQTT(topic, message, qos = 0) {
- if (!client || !client.connected) {
- console.error('MQTT 未连接,无法发布消息')
- return
- }
- // 统一转为字符串
- const msg = typeof message === 'object' ? JSON.stringify(message) : message
- client.publish(topic, msg, { qos }, (error) => {
- if (error) {
- console.error(`发布消息到 ${topic} 失败:`, error)
- } else {
- console.log(`发布消息到 ${topic} 成功:`, msg)
- }
- })
- }
- /**
- * 取消订阅 MQTT 主题
- * @param {String|Array} topic 主题(单个字符串或数组)
- */
- export function unsubscribeMQTT(topic) {
- if (!client || !client.connected) {
- console.error('MQTT 未连接,无法取消订阅')
- return
- }
- client.unsubscribe(topic, (error) => {
- if (error) {
- console.error(`取消订阅 ${topic} 失败:`, error)
- } else {
- console.log(`取消订阅 ${topic} 成功`)
- }
- })
- }
- mqtt.js
复制代码 mqtt.js5.创建在线组件/components/online/online.vue,其中2个getApp().add_log方法是上传连接日志到服务器,请自行删除
- <template>
- <view>
- <view class="topfixed">
- <view class="topfixed_content">
-
- <view class="topNavBox">
- <view class="leftBtnBox">
- <view class="gobackBox color-white font-28">
- <view>设备:</view>
- <block v-if="m_zt==1">
- <view class="flex">
- <u-icon name="pause-circle-fill" color="#00AA59" size="18"></u-icon>
- <view class="ml6">在线</view>
- </view>
- </block>
-
- <block v-else>
- <view class="flex">
- <u-icon name="minus-circle-fill" color="#ff0000" size="18"></u-icon>
- <view class="ml6">离线</view>
- </view>
- </block>
- </view>
-
- </view>
- </view>
-
- <view class="topNavBox">
- <view class="leftBtnBox">
- <view class="gobackBox color-white font-28">
- <view>程序:</view>
- <block v-if="xcx_zt==1">
- <view class="flex" @click="disconnect">
- <u-icon name="pause-circle-fill" color="#00AA59" size="18"></u-icon>
- <view class="ml6">在线</view>
- </view>
- </block>
-
- <block v-else>
- <view class="flex" @click="connect">
- <u-icon name="minus-circle-fill" color="#ff0000" size="18"></u-icon>
- <view class="ml6">离线</view>
- </view>
- </block>
- </view>
-
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
复制代码 online.vue6.App.vue内容,其中add_log方法是上传连接日志到服务器,请自行删除- [/code]
- 7.创建测试文件/pages/index/index.vue,其中tabBar是我自定义的菜单组件,请自行删除
- [align=center]
[/align][align=center]
[/align][code]<template> - <view class="">
- <view>
- <online></online>
- </view>
- <map style="width: 100%; height: 300px;" :latitude="latitude" :longitude="longitude" :style="'height:'+windowHeight*2+'rpx;'">
-
- </map>
-
- <view>
- <tabBar :pageIndex="100" :textType="1" @toTab="toTab"></tabBar>
- </view>
- </view>
- </template>
复制代码 index.vue结果
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |