1、安装mqtt.js (推荐使用3.0.0,兼容性好)
2、封装个对象,配置地址,账号,密码,必要参数,发布,订阅,监听,取消订阅,断开一些方法即可
真机会出现的问题:
地址问题:app,微信环境要使用 wx:// ;web,h5使用 ws://
1、对依赖不兼容,真机运行报错,阅读源码会发现,其实还是底层socket原因。
不要直接改依赖源码,可以在main.js 中进行修复
// #ifndef MP
// 处理 mqtt.js app环境下兼容问题,强制返回 SocketTask
uni.connectSocket = (function(connectSocket) {
return function(options) {
console.log(options)
options.success = options.success || function() {}
return connectSocket.call(this, options)
}
})(uni.connectSocket)
// #endif
2、手机息屏问题:
现象:息屏几秒,再打开,会发现系统会杀死一些进程,mqtt会报错,打印client发现,依然处于链接状态,但监听是收不到消息的;
处理方法:开屏重连,判断息屏场景,在哪判断,在哪执行断开是个核心,选择文件时应用也会进入后台,可在app.vue中进行取消订阅,中断链接操作;每次进入前台要进行释放上次的监听器,并重新绑定(在首页(公共页)编写mqtt的相关逻辑,但不要在app.vue ,因为需要用户信息);上传选择附件场景可用状态标记进行区分
import {onHide} from '@dcloudio/uni-app'
import {useAppHideTypeStore} from "@/stores/onLineDevice.js"
const appHideTypeStore = useAppHideTypeStore()
onHide(()=>{
const page = getCurrentPages()[0];
if(page.$page.fullPath==='/pages/groundStaff/index/index'|| page.$page.fullPath==='/pages/index/index'){
console.log(appHideTypeStore.type,'--进入后台场景val--')
if(appHideTypeStore.type==''){//息屏时进行取消
page.$.exposed.unSub()
}
}
})
// uni.hideTabBar()
3、重复监听问题, 进入内页再回来,会发现出现重复监听。原因就是莫名其妙增加了监听器,依赖自身的缺陷;
方案:不要直接用 箭头函数去接收监听消息,写个函数接收,并记录下来,再在下次绑定事件前释放监听器 ;自定义函数监听,收到的会是unit8Array 二进制数据,自己写个解码函数即可,可用(buffer,utf8)第三方库,返回不同格式数据的处理,避免数据丢失,或者部分平台不兼容问题
//二进制解码
function decodeMessage(message) {
if (message instanceof Uint8Array) {
// 尝试使用 Buffer 解码
return Buffer.from(message).toString('utf8');
} else if (message && typeof message === 'object' && 'byteLength' in message) {
// 尝试使用 utf8 解码 ArrayBuffer
const uint8Array = new Uint8Array(message);
let binary = '';
for (let i = 0; i < uint8Array.byteLength; i++) {
binary += String.fromCharCode(uint8Array[i]);
}
return utf8.decode(binary);
} else if (typeof message === 'string') {
return message;
} else {
console.warn("未知的消息格式:", message);
return String(message);
}
}
4、销毁操作不可放在逻辑页面的onUnmounted钩子, 内页通过 reLaunch 跳转到首页时,会先触发show, 再触发onUnmounted 因为关闭所有页面是异步进行的,会先获取所有页面栈,进入队列。然后打开目标页面
5、建议使用单例模式,不要到处new的都是对象,不好管理,很容易内存溢出