From 0d6ac88dea214bcc45eec19be560f7d146b0fc36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Wed, 3 Sep 2025 09:52:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(websocket):=20=E5=B0=86=E5=AE=A2?= =?UTF-8?q?=E6=9C=8D=E7=8A=B6=E6=80=81=E6=9F=A5=E8=AF=A2=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E5=99=A8=E9=80=BB=E8=BE=91=E7=A7=BB=E8=87=B3websocket=20store?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将原本在组件中的客服状态查询定时器逻辑重构到websocket store中,统一管理定时器的启动和停止。同时在连接成功时自动启动定时器,断开连接时自动停止,避免内存泄漏。 --- Cunkebao/src/pages/pc/ckbox/index.tsx | 15 ----- .../src/store/module/websocket/websocket.ts | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/Cunkebao/src/pages/pc/ckbox/index.tsx b/Cunkebao/src/pages/pc/ckbox/index.tsx index 7376104c..e02d5739 100644 --- a/Cunkebao/src/pages/pc/ckbox/index.tsx +++ b/Cunkebao/src/pages/pc/ckbox/index.tsx @@ -16,8 +16,6 @@ import { weChatGroup, ContractData, } from "@/pages/pc/ckbox/data"; -import { useWebSocketStore } from "@/store/module/websocket/websocket"; -import { useCkChatStore } from "@/store/module/ckchat/ckchat"; const CkboxPage: React.FC = () => { const [messageApi, contextHolder] = message.useMessage(); @@ -25,22 +23,9 @@ const CkboxPage: React.FC = () => { const [currentChat, setCurrentChat] = useState( null, ); - const status = useWebSocketStore(state => state.status); // 不要在组件初始化时获取sendCommand,而是在需要时动态获取 const [loading, setLoading] = useState(false); const [showProfile, setShowProfile] = useState(true); - const kfUserList = useCkChatStore(state => state.kfUserList); - const { sendCommand } = useWebSocketStore.getState(); - useEffect(() => { - if (status == "connected" && kfUserList.length > 0) { - //查询客服用户激活状态 - setInterval(() => { - sendCommand("CmdRequestWechatAccountsAliveStatus", { - wechatAccountIds: kfUserList.map(v => v.id), - }); - }, 10 * 1000); - } - }, [status]); useEffect(() => { // 方法一:使用 Promise 链式调用处理异步函数 diff --git a/Cunkebao/src/store/module/websocket/websocket.ts b/Cunkebao/src/store/module/websocket/websocket.ts index ebfe53a2..a1327038 100644 --- a/Cunkebao/src/store/module/websocket/websocket.ts +++ b/Cunkebao/src/store/module/websocket/websocket.ts @@ -51,6 +51,7 @@ interface WebSocketState { // 重连相关 reconnectAttempts: number; reconnectTimer: NodeJS.Timeout | null; + aliveStatusTimer: NodeJS.Timeout | null; // 客服用户状态查询定时器 // 方法 connect: (config: Partial) => void; @@ -68,6 +69,8 @@ interface WebSocketState { _handleError: (event: Event) => void; _startReconnectTimer: () => void; _stopReconnectTimer: () => void; + _startAliveStatusTimer: () => void; // 启动客服状态查询定时器 + _stopAliveStatusTimer: () => void; // 停止客服状态查询定时器 } // 默认配置 @@ -92,6 +95,7 @@ export const useWebSocketStore = createPersistStore( unreadCount: 0, reconnectAttempts: 0, reconnectTimer: null, + aliveStatusTimer: null, // 连接WebSocket connect: (config: Partial) => { @@ -183,6 +187,7 @@ export const useWebSocketStore = createPersistStore( } currentState._stopReconnectTimer(); + currentState._stopAliveStatusTimer(); set({ status: WebSocketStatus.DISCONNECTED, @@ -291,6 +296,9 @@ export const useWebSocketStore = createPersistStore( } Toast.show({ content: "WebSocket连接成功", position: "top" }); + + // 启动客服状态查询定时器 + currentState._startAliveStatusTimer(); }, // 内部方法:处理消息接收 @@ -319,6 +327,9 @@ export const useWebSocketStore = createPersistStore( }); } + // 停止客服状态查询定时器 + get()._stopAliveStatusTimer(); + // 断开连接 get().disconnect(); return; @@ -414,6 +425,51 @@ export const useWebSocketStore = createPersistStore( set({ reconnectTimer: null }); } }, + + // 内部方法:启动客服状态查询定时器 + _startAliveStatusTimer: () => { + const currentState = get(); + + // 先停止现有定时器 + currentState._stopAliveStatusTimer(); + + // 获取客服用户列表 + const { kfUserList } = useCkChatStore.getState(); + + // 如果没有客服用户,不启动定时器 + if (!kfUserList || kfUserList.length === 0) { + return; + } + + // 启动定时器,每5秒查询一次 + const timer = setInterval(() => { + const state = get(); + // 检查连接状态 + if (state.status === WebSocketStatus.CONNECTED) { + const { kfUserList: currentKfUserList } = useCkChatStore.getState(); + if (currentKfUserList && currentKfUserList.length > 0) { + state.sendCommand("CmdRequestWechatAccountsAliveStatus", { + wechatAccountIds: currentKfUserList.map(v => v.id), + }); + } + } else { + // 如果连接断开,停止定时器 + state._stopAliveStatusTimer(); + } + }, 5000); + + set({ aliveStatusTimer: timer }); + }, + + // 内部方法:停止客服状态查询定时器 + _stopAliveStatusTimer: () => { + const currentState = get(); + + if (currentState.aliveStatusTimer) { + clearInterval(currentState.aliveStatusTimer); + set({ aliveStatusTimer: null }); + } + }, }), { name: "websocket-store", @@ -424,6 +480,7 @@ export const useWebSocketStore = createPersistStore( messages: state.messages.slice(-100), // 只保留最近100条消息 unreadCount: state.unreadCount, reconnectAttempts: state.reconnectAttempts, + // 注意:定时器不需要持久化,重新连接时会重新创建 }), onRehydrateStorage: () => state => { // 页面刷新后,如果之前是连接状态,尝试重新连接