1.0.3 的相关功能

This commit is contained in:
浅念
2025-08-19 16:18:15 +08:00
parent 0e84bedb67
commit 70d26f0829
10 changed files with 774 additions and 167 deletions
+124
View File
@@ -0,0 +1,124 @@
import mittBus from './mittBus'
import { useUserStore } from '@/store/modules/user'
type JsonValue = Record<string, any> | any[]
const WS_BASE = 'wss://mzl.dev.hnxinyouhe.com/ws?token='
let socket: WebSocket | null = null
let reconnectTimer: any = null
let heartbeatTimer: any = null
let reconnectAttempts = 0
const maxReconnectDelayMs = 30000
const heartbeatIntervalMs = 30000
const getReconnectDelay = () => {
const base = 1000 * Math.pow(2, reconnectAttempts)
return Math.min(base, maxReconnectDelayMs)
}
const cleanup = () => {
if (reconnectTimer) {
clearTimeout(reconnectTimer)
reconnectTimer = null
}
if (heartbeatTimer) {
clearTimeout(heartbeatTimer)
heartbeatTimer = null
}
}
const startHeartbeat = () => {
// 清理上一次的心跳
if (heartbeatTimer) {
clearTimeout(heartbeatTimer)
heartbeatTimer = null
}
// 递归 setTimeout,确保固定间隔执行
heartbeatTimer = setTimeout(() => {
try {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ type: 'ping' }))
}
} catch (_) {}
// 下一次心跳
startHeartbeat()
}, heartbeatIntervalMs)
}
const scheduleReconnect = () => {
cleanup()
const delay = getReconnectDelay()
reconnectTimer = setTimeout(() => {
const { accessToken } = useUserStore()
if (accessToken) initWebSocket(accessToken)
}, delay)
}
export const initWebSocket = (token: string) => {
try {
if (!token) return
if (socket) {
try {
socket.close()
} catch (_) {}
socket = null
}
cleanup()
const url = `${WS_BASE}${token}`
socket = new WebSocket(url)
socket.onopen = () => {
reconnectAttempts = 0
startHeartbeat()
mittBus.emit('ws:open')
try {
socket?.send(JSON.stringify({ type: 'ping' }))
} catch (_) {}
}
socket.onmessage = (event) => {
const dataStr = event.data
let data: any = dataStr
try {
data = JSON.parse(dataStr)
} catch (_) {}
mittBus.emit('ws:message', data)
}
socket.onerror = (err) => {
mittBus.emit('ws:error', err)
}
socket.onclose = () => {
mittBus.emit('ws:close')
reconnectAttempts += 1
scheduleReconnect()
}
} catch (e) {
mittBus.emit('ws:error', e)
scheduleReconnect()
}
}
export const closeWebSocket = () => {
cleanup()
try {
socket?.close()
} catch (_) {}
socket = null
}
export const sendWebSocket = (payload: string | JsonValue) => {
if (!socket || socket.readyState !== WebSocket.OPEN) return false
try {
const data = typeof payload === 'string' ? payload : JSON.stringify(payload)
socket.send(data)
return true
} catch (_) {
return false
}
}