从这篇文章接着向下看:
uniapp plus-websocket 和stompjs连接教程 安卓ios手机端有效 - 简书
按照文章的方式,能够实现APP下stmopjs长连接。但是有一个问题,就是会频繁输出
res-创建连接-1-
跟踪连接,会发现连接都会在大约40s后掉线断开,然后由于stompjs保活机制又进行重连。在重连过程中,对应的消息接收不到。导致出现部分消息丢失的情况。
目前解决的办法,是自己实现一个心跳逻辑,每隔指定的时间发送。就完成了连接保活。修改如下:
import socket from 'plus-websocket'
class WebSocketPolyfill {
constructor(url) {
。。。。
connected() {
return socket.connected
}
}
export default WebSocketPolyfill
client = new Client({
// #ifndef H5
webSocketFactory() {
if (isMp) {
// 微信小程序
return new Ws({
url: amqpServerUrl,
protocols: ['v12.stomp', 'v11.stomp', 'v10.stomp'] // ← 这是 stomp 协议的默认写法,可供参考
})
} else {
appWs = new WebSocket(amqpServerUrl)
return appWs
// Android | IOS
}
},
。。。。。
const appHeartbeat = () => {
setTimeout(() => {
if (appWs.connected) {
const buffer = new ArrayBuffer(1) // 创建一个1字节的ArrayBuffer
const view = new Uint8Array(buffer)
view[0] = 0x09 // 根据RFC6455, opcode 0x9 表示ping帧
appWs.send(buffer)
appHeartbeat()
}
}, HEARTBEAT_INTERVAL)
}
然后在onConnect后激活心跳
onConnect: () => {
// connect to user channel....
// #ifdef APP-PLUS
appHeartbeat()
// #endif
},
这样就解决了掉线问题
----------------------[2024/11/21新增]-----------------------
长链接睡死问题的解决
当屏幕休眠超过20分钟时,在IOS及安卓系统可能由于资源释放导致socket无法重连。上面这种方案无法直接断开链接重连。必须通过重载APP解决,因此实现一个变量和两个方法,在APP隐藏显示时进行计算,如果熄屏或挂起超过20分钟,则加载首页来实现长链接重载。
let hideTick: number = -1
export const watchHide = () => {
hideTick = new Date().getTime()
}
export const watchShow = async () => {
// 如果休息时间太久,就回首页重置长连接,避免睡死
if (
hideTick > 0 &&
new Date().getTime() - hideTick > FORCE_RECONNECT_ON_SLEEP_SEC &&
currentUserId
) {
await leaveUserChannel() //deactivate长链接,close socket
setTimeout(() => {
// 休息太久了,去首页
utils.reLaunch('/pages/index/index')
}, 1000)
}
hideTick = -1
}
在APP.vue的show和hide分别执行watchShow和watchHide即可
下面是完整的plus-websocket封装单元(该单元已废弃,由于plus-websocket大并发时丢失消息的问题,已重写替代模块,请见我另一篇《plus-websocket替代websocket封装模块》:
websocket-app.js:
/**
* 封装 plus-websocket 文件
*/
import socket from 'plus-websocket'
class WebSocketPolyfill {
constructor(url) {
// 创建连接
socket.connectSocket({
url,
success: function (res) {
console.log('res-创建连接-1-', res)
}
})
// 连接开启
socket.onSocketOpen((res) => {
this.onopen(res)
})
// 连接关闭
socket.onSocketClose((res) => {
this.onclose(res)
})
// 连接异常
socket.onSocketError((res) => {
this.onerror(res)
})
// 接收消息
socket.onSocketMessage((res) => {
this.onmessage(res)
})
}
/**
* 连接开启
*/
onopen(res) {}
/**
* 连接关闭
*/
onclose(res) {}
/**
* 连接异常
*/
onerror(res) {}
/**
* 接收消息
*/
onmessage(res) {}
/**
* 发送消息
*/
send(data) {
socket.sendSocketMessage({
data
})
}
/**
* 关闭连接
*/
close() {
socket.closeSocket()
}
connected() {
return socket.connected
}
}
export default WebSocketPolyfill