const state = { ws: null, // 保存 WebSocket 实例 heartCheckTimer: null, // 心跳检测计时器 connectionStatus: 'disconnected', // 连接状态 shouldReconnect: true, // 是否应该重新连接 reconnectAttempts: 0, // 重连次数 maxReconnectAttempts: 5, // 最大重连次数 shouldStartHeartCheck: false // 是否应该启动心跳检测 } const mutations = { // 设置 WebSocket 实例 SET_WS(state, ws) { state.ws = ws console.log('SET_WS', state.ws) }, // 清除 WebSocket 实例 CLEAR_WS(state) { state.ws = null }, // 设置心跳检测计时器 SET_HEART_CHECK_TIMER(state, timer) { state.heartCheckTimer = timer }, // 设置连接状态 SET_CONNECTION_STATUS(state, status) { state.connectionStatus = status }, // 设置是否重新连接标志 SET_SHOULD_RECONNECT(state, flag) { state.shouldReconnect = flag }, // 更新重连次数 INCREMENT_RECONNECT_ATTEMPTS(state) { state.reconnectAttempts++ }, RESET_RECONNECT_ATTEMPTS(state) { state.reconnectAttempts = 0 }, // 设置是否应该启动心跳检测 SET_SHOULD_START_HEART_CHECK(state, flag) { state.shouldStartHeartCheck = flag } } const actions = { // 启动 WebSocket 连接 startWebSocket({commit, dispatch, state}, startHeartCheck = false) { if (!state.ws || state.ws.readyState !== WebSocket.OPEN) { console.log('Attempting to connect to WebSocket...') const socketUrl = `${window.context.WebSocket}/websocket` console.log('Connecting to:', socketUrl) const ws = new WebSocket(socketUrl) // 绑定事件处理函数 ws.onmessage = (e) => handleIncomingMessage(e, state.ws) ws.onclose = () => handleSocketClose(dispatch, commit, state) ws.onopen = () => handleSocketOpen(commit, dispatch, ws, startHeartCheck) ws.onerror = (e) => handleSocketError(e, commit, dispatch) // 保存 WebSocket 实例 commit('SET_WS', ws) commit('SET_SHOULD_START_HEART_CHECK', startHeartCheck) } }, // 发送 WebSocket 消息 sendWebSocketMessage({state}, msg = '') { return new Promise((resolve, reject) => { // 检查 WebSocket 是否连接正常 if (state.ws?.readyState === WebSocket.OPEN) { try { console.log(`${new Date().toLocaleString()} >>>>> 发送消息:${msg}`, state.ws) state.ws.send(msg) resolve('消息发送成功') } catch (error) { console.error('发送 WebSocket 消息时出现错误:', error) reject(error) } } else { const error = new Error('WebSocket 未连接或连接已关闭,无法发送消息') console.error(error.message) reject(error) } }) }, // 尝试重新连接 WebSocket reconnectWebSocket({dispatch, state, commit}) { if (state.shouldReconnect && state.reconnectAttempts < state.maxReconnectAttempts) { // 增加重连次数 commit('INCREMENT_RECONNECT_ATTEMPTS') console.log('Reconnecting attempt:', state.reconnectAttempts) // 清除现有的 WebSocket 连接 dispatch('clearWebSocket') // 6秒后尝试重新连接 setTimeout(() => { dispatch('startWebSocket', state.shouldStartHeartCheck) }, 6000) } else { console.error('已达到最大重连次数,停止重连') commit('SET_SHOULD_RECONNECT', false) } }, // 清除 WebSocket 连接 clearWebSocket({commit, dispatch, state}) { if (state.ws) { console.log('Closing WebSocket connection') state.ws.onclose = null // 取消现有的 onclose 事件处理程序 state.ws.close() commit('CLEAR_WS') commit('SET_CONNECTION_STATUS', 'disconnected') commit('SET_SHOULD_START_HEART_CHECK', false) // 重置心跳检测标志 dispatch('clearHeartCheckTimer') } }, // 开始心跳检测 startHeartCheck({commit, dispatch, state}) { console.log(`${new Date().toLocaleString()} >>>>> 开始心跳检测`, state.ws) // 清除之前的心跳检测计时器 dispatch('clearHeartCheckTimer') // 发送初始心跳消息 dispatch('sendWebSocketMessage', JSON.stringify({type: 'ping'})) // 设置定时器每59秒发送一次心跳消息 const timer = setInterval(() => { // 检查 WebSocket 是否连接正常 if (!state.ws || state.ws.readyState !== WebSocket.OPEN) { console.log(`${new Date().toLocaleString()} >>>>> 心跳检测失败,触发重连`, state.ws) dispatch('reconnectWebSocket') } else { console.log(`${new Date().toLocaleString()} >>>>> 心跳正常,继续下一次心跳检测`, state.ws) dispatch('sendWebSocketMessage', JSON.stringify({type: 'ping'})) } }, 1000 * 59) // 保存心跳检测计时器 commit('SET_HEART_CHECK_TIMER', timer) }, // 清除心跳检测计时器 clearHeartCheckTimer({commit, state}) { const timer = state.heartCheckTimer if (timer) clearInterval(timer) commit('SET_HEART_CHECK_TIMER', null) } } // 处理收到的 WebSocket 消息 function handleIncomingMessage(e, ws) { console.log(`${new Date().toLocaleString()} >>>>> 收到消息 ${e.data}`, ws) } // 处理 WebSocket 关闭事件 function handleSocketClose(dispatch, commit, state) { console.log(`${new Date().toLocaleString()} >>>>> 连接已关闭`) commit('SET_CONNECTION_STATUS', 'disconnected') if (state.shouldReconnect) { dispatch('reconnectWebSocket') } } // 处理 WebSocket 连接成功事件 function handleSocketOpen(commit, dispatch, ws, startHeartCheck) { console.log('WebSocket connection opened:', ws) commit('SET_CONNECTION_STATUS', 'connected') commit('SET_WS', ws) commit('SET_SHOULD_RECONNECT', true) // 允许重新连接 commit('RESET_RECONNECT_ATTEMPTS') // 重置重连次数 if (startHeartCheck) { dispatch('startHeartCheck') // 在连接成功后启动心跳检测 } } // 处理 WebSocket 错误事件 function handleSocketError(e, commit, dispatch) { console.log('WebSocket error occurred:', e) commit('SET_CONNECTION_STATUS', 'error') dispatch('clearWebSocket') // 处理错误时清除 WebSocket 连接 if (state.shouldReconnect) { dispatch('reconnectWebSocket') } } export default { state, mutations, actions }