/* eslint-disable camelcase */
// websocket连接
let websocket_connected_count = 0
// const onclose_connected_count = 0
const callback: any = null
const token: any = null
let socketUrl: any = '' // socket地址
export let websockets: any = null // websocket 实例
const seTime: any = ref()
const msg: any = null
export function initWebSocket(url: any, token: any, callback: any = null, msg: any = null) {
//console.log(url, 'url')
if (msg == '鉴权失败') {
websockets.close()
} else {
seTime.value = setTimeout(() => {
const websocket = null
// 判断当前环境是否支持websocket
if (window.WebSocket) {
if (!websocket) {
socketUrl = url
websockets = new WebSocket(url, token)
//console.log(websockets, 'window.WebSocket')
}
} else {
// console.log('not support websocket')
}
// 连接成功建立的回调方法
websockets.onopen = function () {
heartCheck.reset().start() // 成功建立连接后,重置心跳检测
// console.log('connected successfully')
}
// 连接发生错误,连接错误时会继续尝试发起连接(尝试5次)
websockets.onerror = function () {
//console.log('onerror连接发生错误')
websocket_connected_count++
if (websocket_connected_count <= 5) {
if (seTime.value) {
clearTimeout(seTime.value)
initWebSocket(socketUrl, token, callback, '')
}
}
}
// 接受到消息的回调方法
websocketonmessage(callback)
// 接受到服务端关闭连接时的回调方法
websockets.onclose = function () {
//console.log('onclose断开连接')
if (seTime.value) {
clearTimeout(seTime.value)
// initWebSocket(socketUrl, token, callback, '')
}
// initWebSocket(socketUrl, token, callback)
}
// 监听窗口事件,当窗口关闭时,主动断开websocket连接,防止连接没断开就关闭窗口,server端报错
window.onbeforeunload = function () {
websockets.close()
}
}, 5000)
}
// 心跳检测, 每隔一段时间检测连接状态,如果处于连接中,就向server端主动发送消息,来重置server端与客户端的最大连接时间,如果已经断开了,发起重连。
}
let heartCheck = {
timeout: 540000, // 9分钟发一次心跳,比server端设置的连接时间稍微小一点,在接近断开的情况下以通信的方式去重置连接时间。
serverTimeoutObj: null as any,
// eslint-disable-next-line object-shorthand
reset: function () {
// clearTimeout(heartCheck.timeout)
clearTimeout(heartCheck.serverTimeoutObj)
return heartCheck
},
start() {
heartCheck.serverTimeoutObj = setInterval(() => {
if (websockets.readyState == 1) {
// console.log('连接状态,发送消息保持连接')
websockets.send('ping')
heartCheck.reset().start() // 如果获取到消息,说明连接是正常的,重置心跳检测
} else {
//console.log('断开状态,尝试重连')
// initWebSocket(socketUrl, token, callback)
if (seTime.value) {
clearTimeout(seTime.value)
initWebSocket(socketUrl, token, callback, '')
}
}
}, heartCheck.timeout)
}
}
const websocketonmessage = (callback: any) => {
websockets.onmessage = function (e) {
//console.log('接受到消息了')
heartCheck.reset().start() // 如果获取到消息,说明连接是正常的,重置心跳检测
if (e.data == 'pong' || e.data.includes('连接成功')) {
return
} else {
const message = JSON.parse(e.data)
if (message) {
//执行接收到消息的操作,一般是刷新UI
// console.log(message, 'message')
callback(message)
}
}
}
}
vue3使用websoket长连接,心跳机制方法封装
于 2024-04-25 09:22:50 首次发布