refactor(websocket): 将客服状态查询定时器逻辑移至websocket store
将原本在组件中的客服状态查询定时器逻辑重构到websocket store中,统一管理定时器的启动和停止。同时在连接成功时自动启动定时器,断开连接时自动停止,避免内存泄漏。
This commit is contained in:
@@ -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<ContractData | weChatGroup>(
|
||||
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 链式调用处理异步函数
|
||||
|
||||
@@ -51,6 +51,7 @@ interface WebSocketState {
|
||||
// 重连相关
|
||||
reconnectAttempts: number;
|
||||
reconnectTimer: NodeJS.Timeout | null;
|
||||
aliveStatusTimer: NodeJS.Timeout | null; // 客服用户状态查询定时器
|
||||
|
||||
// 方法
|
||||
connect: (config: Partial<WebSocketConfig>) => 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<WebSocketState>(
|
||||
unreadCount: 0,
|
||||
reconnectAttempts: 0,
|
||||
reconnectTimer: null,
|
||||
aliveStatusTimer: null,
|
||||
|
||||
// 连接WebSocket
|
||||
connect: (config: Partial<WebSocketConfig>) => {
|
||||
@@ -183,6 +187,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
|
||||
}
|
||||
|
||||
currentState._stopReconnectTimer();
|
||||
currentState._stopAliveStatusTimer();
|
||||
|
||||
set({
|
||||
status: WebSocketStatus.DISCONNECTED,
|
||||
@@ -291,6 +296,9 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
|
||||
}
|
||||
|
||||
Toast.show({ content: "WebSocket连接成功", position: "top" });
|
||||
|
||||
// 启动客服状态查询定时器
|
||||
currentState._startAliveStatusTimer();
|
||||
},
|
||||
|
||||
// 内部方法:处理消息接收
|
||||
@@ -319,6 +327,9 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
|
||||
});
|
||||
}
|
||||
|
||||
// 停止客服状态查询定时器
|
||||
get()._stopAliveStatusTimer();
|
||||
|
||||
// 断开连接
|
||||
get().disconnect();
|
||||
return;
|
||||
@@ -414,6 +425,51 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
|
||||
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<WebSocketState>(
|
||||
messages: state.messages.slice(-100), // 只保留最近100条消息
|
||||
unreadCount: state.unreadCount,
|
||||
reconnectAttempts: state.reconnectAttempts,
|
||||
// 注意:定时器不需要持久化,重新连接时会重新创建
|
||||
}),
|
||||
onRehydrateStorage: () => state => {
|
||||
// 页面刷新后,如果之前是连接状态,尝试重新连接
|
||||
|
||||
Reference in New Issue
Block a user