效果图
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