You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
5.6 KiB
224 lines
5.6 KiB
/*
|
|
* @description: 封装socket方法
|
|
* @date: 2023-01-20
|
|
* @author: 郭安鹏
|
|
*/
|
|
import { ElMessage } from 'element-plus'
|
|
import { ref } from 'vue'
|
|
|
|
export const isClose = ref(true)
|
|
|
|
interface socket {
|
|
appKey: any
|
|
websocket: any
|
|
connectURL: string
|
|
socket_open: boolean
|
|
hearBeat_timer: any
|
|
hearBeat_interval: number
|
|
is_reconnect: boolean
|
|
reconnect_count: number
|
|
reconnect_current: number
|
|
reconnect_number: number
|
|
reconnect_timer: any
|
|
reconnect_interval: number
|
|
receiveMessageCallBackObj: any
|
|
initCallBacks: any
|
|
// eslint-disable-next-line ts/no-unsafe-function-type
|
|
receiveMessage: Function
|
|
// eslint-disable-next-line ts/no-unsafe-function-type
|
|
registerCallback: Function
|
|
// eslint-disable-next-line ts/no-unsafe-function-type
|
|
registerInitCallback: Function
|
|
// eslint-disable-next-line ts/no-unsafe-function-type
|
|
init: (receiveMessage?: Function | null, type?: string, connectURL?: string) => any
|
|
heartbeat: () => void
|
|
heartSend: () => void
|
|
send: (data: any, callback?: any) => void
|
|
close: () => void
|
|
reconnect: () => void
|
|
sendAppJoin: () => void
|
|
}
|
|
|
|
// eslint-disable-next-line ts/no-redeclare
|
|
export const socket: socket = {
|
|
appKey: null,
|
|
websocket: null,
|
|
connectURL: import.meta.env.FT_WS_URL,
|
|
// 开启标识
|
|
socket_open: false,
|
|
// 心跳timer
|
|
hearBeat_timer: null,
|
|
// 心跳发送频率
|
|
hearBeat_interval: 500,
|
|
// 是否需要重连
|
|
is_reconnect: true,
|
|
// 重连次数
|
|
reconnect_count: 10,
|
|
// 已发起重连次数
|
|
reconnect_current: 1,
|
|
// 网络错误提示此时
|
|
reconnect_number: 0,
|
|
// 重连timer
|
|
reconnect_timer: null,
|
|
// 重连频率
|
|
reconnect_interval: 1000,
|
|
|
|
receiveMessageCallBackObj: {},
|
|
initCallBacks: [],
|
|
// eslint-disable-next-line ts/no-unsafe-function-type
|
|
registerInitCallback: (fn: Function, ...args: any) => {
|
|
// socket 连接成功后的回调
|
|
socket.initCallBacks.push({
|
|
fn,
|
|
args,
|
|
})
|
|
},
|
|
// 接收消息的方法
|
|
receiveMessage: (e: any) => {
|
|
const message = JSON.parse(e.data)
|
|
const fn = socket.receiveMessageCallBackObj[message.type]
|
|
if (fn) {
|
|
fn(message)
|
|
}
|
|
else {
|
|
console.error('请注册当前类型的回调函数', message)
|
|
}
|
|
},
|
|
registerCallback: (fn: any, type: any) => {
|
|
// 接收消息的回调
|
|
socket.receiveMessageCallBackObj[type] = fn
|
|
},
|
|
|
|
init: async (
|
|
receiveMessageCallBack: any,
|
|
type?: string,
|
|
connectURL?: string,
|
|
reconnection?: boolean,
|
|
) => {
|
|
if (!('WebSocket' in window)) {
|
|
ElMessage.warning('浏览器不支持WebSocket')
|
|
return null
|
|
}
|
|
|
|
// 注册回调函数
|
|
if (receiveMessageCallBack && type) {
|
|
socket.registerCallback(receiveMessageCallBack, type)
|
|
}
|
|
// 已经创建过连接无需重复创建
|
|
if (socket.websocket && !reconnection) {
|
|
return socket.websocket
|
|
}
|
|
|
|
await new Promise((rs) => {
|
|
socket.websocket = new WebSocket(connectURL || socket.connectURL)
|
|
// 消息接收
|
|
socket.websocket.onmessage = (e: any) => {
|
|
socket.receiveMessage(e)
|
|
}
|
|
// socket关闭
|
|
socket.websocket.onclose = () => {
|
|
console.error('onclose')
|
|
|
|
clearInterval(socket.hearBeat_interval)
|
|
socket.socket_open = false
|
|
isClose.value = true
|
|
// 需要重新连接
|
|
if (socket.is_reconnect) {
|
|
socket.reconnect_timer = setTimeout(() => {
|
|
// 超过重连次数
|
|
// if (socket.reconnect_current > socket.reconnect_count) {
|
|
// clearTimeout(socket.reconnect_timer);
|
|
// socket.is_reconnect = false;
|
|
// console.error('超出重连次数,不再重连', new Date());
|
|
// return;
|
|
// }
|
|
// 记录重连次数
|
|
socket.reconnect_current++
|
|
socket.reconnect()
|
|
}, socket.reconnect_interval)
|
|
}
|
|
}
|
|
// 连接发生错误
|
|
socket.websocket.onerror = function () {
|
|
console.error('onerror')
|
|
isClose.value = true
|
|
socket.socket_open = false
|
|
}
|
|
// 连接成功
|
|
socket.websocket.onopen = function () {
|
|
socket.socket_open = true
|
|
socket.is_reconnect = true
|
|
// 开启心跳
|
|
socket.heartbeat()
|
|
// 连接成功后发起app加入消息
|
|
socket.sendAppJoin()
|
|
|
|
for (const fnItem of socket.initCallBacks) {
|
|
fnItem.fn(...fnItem.args)
|
|
}
|
|
|
|
isClose.value = false
|
|
|
|
rs(true) // socket 已连接
|
|
}
|
|
})
|
|
},
|
|
|
|
send: (data, callback = null) => {
|
|
// 开启状态直接发送
|
|
if (socket.websocket.readyState === socket.websocket.OPEN) {
|
|
socket.websocket.send(JSON.stringify(data))
|
|
if (callback) {
|
|
callback()
|
|
}
|
|
}
|
|
else {
|
|
clearInterval(socket.hearBeat_timer)
|
|
socket.reconnect_number++
|
|
}
|
|
},
|
|
|
|
heartbeat: () => {
|
|
if (socket.hearBeat_timer) {
|
|
clearInterval(socket.hearBeat_timer)
|
|
}
|
|
socket.hearBeat_timer = setInterval(() => {
|
|
socket.heartSend()
|
|
}, socket.hearBeat_interval)
|
|
},
|
|
heartSend: () => {
|
|
socket.send({
|
|
type: 'ping', // ping
|
|
})
|
|
},
|
|
close: () => {
|
|
clearInterval(socket.hearBeat_timer)
|
|
socket.is_reconnect = false
|
|
socket.websocket && socket.websocket.close()
|
|
socket.websocket = null
|
|
},
|
|
|
|
/**
|
|
* 重新连接
|
|
*/
|
|
reconnect: () => {
|
|
if (socket.websocket) {
|
|
// 需要重连
|
|
if (socket.is_reconnect) {
|
|
socket.websocket.close()
|
|
socket.websocket = null
|
|
socket.init()
|
|
}
|
|
else {
|
|
socket.close()
|
|
}
|
|
}
|
|
},
|
|
|
|
sendAppJoin: () => {
|
|
socket.send({
|
|
appKey: socket.appKey,
|
|
type: 1, // appJoin
|
|
})
|
|
},
|
|
}
|