[转载]uniapp使用Mqtt-页面实时更新数据

效果图

mqtt参考文档:MQTT.js 入门教程 | EMQ、MQTT.js 入门教程 - EMQX - 博客园

以下代码使用mqtt兼容H5、App、微信小程序、支付宝小程序

一.安装mqtt依赖包
1.H5和App、微信小程序,统一使用依赖包的mqtt文件

npm  i  mqtt@3.0.0

2.支付宝小程序,需要在官网下载mqtt.min.js文件,存放路径:/utils/mqtt.min.js

下载js文件链接: https://pan.baidu.com/s/1KHE7FRa_GGQE0DM1U4pjcQ?pwd=5xuy

参考文档:快速使用MQTT 支付宝小程序 SDK实现消息收发 [IM 开发文档]

参考github代码:GitHub - Wster11/zhifubao-mqtt-demo

二.封装成工具包
/utils/sendMqtt.js 

// #ifdef H5
const mqtturl = "wss://";
var mqtt = require('mqtt/dist/mqtt.js')
// #endif
 
// #ifdef APP-PLUS || MP-WEIXIN
const mqtturl = "wxs://";
var mqtt = require('mqtt/dist/mqtt.js')
//#endif
 
// #ifdef MP-ALIPAY
const mqtturl = "alis://";
var mqtt = require('@/utils/mqtt.min.js')
// import mqtt from "@/utils/mqtt.min.js" // 或者这样引入
//#endif
 
function messageid2() {
    // 2位随机数
    return Math.floor(Math.random() * (99 - 10)) + 10;
}
 
var client;
 
// 创建MQTT连接
const createMqtt = () => {
    let options = {
        keepalive: 30,
        clientId: "你的clientId", // 例如:`${apptype}_${member_id}_${uid}_${messageid2()}` `H5_88_99_${messageid2()}`
        protocolId: 'MQTT',
        username: "你的username",
        password: "你的password",
        protocolVersion: 4,
        clean: true,
        reconnectPeriod: 1000, // reconnectPeriod为1000毫秒,这意味着在连接丢失之后,客户端将在1秒后尝试重新连接。
        connectTimeout: 5000, // 5s超时时间 意味着mqtt-reconnect函数5秒钟触发一次
        topic: "你的topic",
        rejectUnauthorized: false,
        // #ifdef MP-ALIPAY
        my: my,//注意这里的my
        //#endif
    }
 
    try {
        if (!client) {
            client = mqtt.connect("你的mqtturl", options);
            initEventHandleMqtt(options.topic);
        }
    } catch (e) {}
};
 
//建立连接  
const initEventHandleMqtt = (topicUrl) => {
    // 当连接成功时触发
    client.on("connect", function() {
        uni.hideLoading()
        console.log("mqtt连接成功");
        //订阅主题 presence
        client.subscribe(topicUrl, function(err) {
            console.log("mqtt订阅主题");
        });
    });
 
    //如果mqttws订阅主题成功,那么这里就是当接收到自己订阅主题的处理逻辑
    client.on("message", function(topic, message) {
        // 获取信息
        const mqttData = JSON.parse(message);
        // 传递信息
        uni.$emit("mqttData", mqttData);
    });
 
    // 当断开连接后,经过重连间隔时间重新自动连接到 Broker 时触发
    client.on('reconnect', function() {
        uni.showLoading({
            title: "重新连接"
        })
    })
 
    // 当客户端无法成功连接时或发生解析错误时触发,参数 error 为错误信息
    client.on("error", function(err) {
        console.log('mqtt---error...', err)
    });
 
    // 在收到 Broker 发送过来的断开连接的报文时触发
    client.on('disconnect', function() {})
 
    // 在断开连接以后触发
    client.on("close", function() {});
 
    // 当客户端下线时触发
    client.on("offline", function() {});
};
 
//强制断开Mqtt
const closeMqtt = () => {
    client?.end()
    client = null
};
 
// 使用pingResp心跳判断客户端和服务端是否还在连接着
const judgeBeat = () => {
    if (client && client.pingResp === false) {}
}
 
export {
    createMqtt,
    closeMqtt,
    client,
}
三.全局引入调用
App.vue

import { createMqtt } from '@/utils/sendMqtt.js';        
 
onLaunch() {
    createMqtt();
},
四.在页面接收数据
接收到的数据,给页面赋值,实现实时更新页面数据

<script>
    export default {
        mounted() {
            // 接收Mqtt信息
            uni.$on('mqttData', (msgData) => {
                console.log("接收到的信息--",msgData);
            });
        },
    }
</script>
五.测试
此时,在控制台可以看到mqtt连接成功。

六.mqtt的问题和解决方法
经H5、App、小程序测试发现问题:切换网络或断开网络mqtt会监听不到,触发mqtt事件就会报错。应用缩小化或手机熄屏mqtt偶尔会停止心跳。

解决方法1:为了保持mqtt长期在连接中,建议设置心跳间隔时间keepalive为1秒,即使在某种情况(应用缩小化、手机熄屏、网络问题)mqtt断开或掉线后,只要应用在线mqtt只需一秒钟就会监听到客户端离线,然后马上就会自动重连。

解决方法2:如果设置心跳间隔时间keepalive为几十秒,需要监听网络和心跳,当切换网络或断开网络强制断开和重连mqtt,当心跳停止也需要强制断开和重连mqtt。

App.vue 设置监听网络和心跳

<script>
    import {
        createMqtt,
        closeMqtt,
        judgeBeat
    } from '@/utils/sendMqtt.js';
 
    export default {
        globalData: {
            isShowModal: false,
        },
        methods: {
            onNetworkStatusChange(res) {
                if (res.isConnected) { // 网络已连接
                    uni.showLoading({
                        title: '网络已连接,等待重连...'
                    })
                    closeMqtt()
                    createMqtt()
                } else { // 在这里执行断网后的逻辑
                    // 定义一个变量isShowModal避免多次触发uni.showModal导致重叠问题
                    if (getApp().globalData.isShowModal) return
                    getApp().globalData.isShowModal = true
                    uni.showModal({
                        title: "提示",
                        showCancel: false,
                        content: "网络已断开,无法操控设备",
                        success: (res) => {
                            if (res.confirm) {
                                getApp().globalData.isShowModal = false
                            }
                        }
                    })
                }
            }
        },
        onLaunch() {
            createMqtt();
            uni.onNetworkStatusChange(this.onNetworkStatusChange);
        },
        onUnload() {
            uni.offNetworkStatusChange(this.onNetworkStatusChange);
        },
        onShow() {
            judgeBeat();
        },
    }
</script>
/utils/sendMqtt.js

// 使用pingResp心跳判断客户端和服务端是否还在连接着
const judgeBeat = () => {
    if (client && client.pingResp === false) {
        uni.showLoading({
            title: "心跳停止,等待重连..."
        })
        closeMqtt()
        createMqtt()
    }
}
                        
原文链接:https://blog.youkuaiyun.com/weixin_52830464/article/details/139269012

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值