refactor(websocket): 重构websocket模块并添加消息管理器

- 将websocket模块拆分为多个文件,提高代码可维护性
- 新增msgManage.ts处理不同类型的websocket消息
- 优化消息处理逻辑,减少重复代码
- 更新相关文件引用路径
This commit is contained in:
超级老白兔
2025-09-02 09:52:38 +08:00
parent cfa8182789
commit 20658c3ca5
8 changed files with 151 additions and 56 deletions

View File

@@ -4,7 +4,7 @@ import {
useWebSocketStore,
WebSocketStatus,
WebSocketMessage,
} from "@/store/module/websocket";
} from "@/store/module/websocket/websocket";
/**
* WebSocket使用示例组件

View File

@@ -38,7 +38,10 @@ import {
import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { getMessages } from "@/pages/pc/ckbox/api";
import styles from "./ChatWindow.module.scss";
import { useWebSocketStore, WebSocketMessage } from "@/store/module/websocket";
import {
useWebSocketStore,
WebSocketMessage,
} from "@/store/module/websocket/websocket";
import { formatWechatTime } from "@/utils/common";
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
import Person from "./components/Person";

View File

@@ -16,8 +16,9 @@ import {
weChatGroup,
ContractData,
} from "@/pages/pc/ckbox/data";
import { useWebSocketStore } from "@/store/module/websocket";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
const CkboxPage: React.FC = () => {
const [messageApi, contextHolder] = message.useMessage();
const [contracts, setContacts] = useState<any[]>([]);
@@ -25,11 +26,20 @@ const CkboxPage: React.FC = () => {
null,
);
const status = useWebSocketStore(state => state.status);
const messages = useWebSocketStore(state => state.messages);
// 不要在组件初始化时获取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") {
//获取UserId
sendCommand("CmdRequestWechatAccountsAliveStatus", {
wechatAccountIds: kfUserList.map(v => v.id),
seq: +new Date(),
});
}
}, [status]);
useEffect(() => {
// 方法一:使用 Promise 链式调用处理异步函数

View File

@@ -6,7 +6,7 @@ import {
asyncCountLables,
useCkChatStore,
} from "@/store/module/ckchat/ckchat";
import { useWebSocketStore } from "@/store/module/websocket";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
import {
loginWithToken,

View File

@@ -2,13 +2,13 @@
export * from "./module/user";
export * from "./module/app";
export * from "./module/settings";
export * from "./module/websocket";
export * from "./module/websocket/websocket";
// 导入store实例
import { useUserStore } from "./module/user";
import { useAppStore } from "./module/app";
import { useSettingsStore } from "./module/settings";
import { useWebSocketStore } from "./module/websocket";
import { useWebSocketStore } from "./module/websocket/websocket";
// 导出持久化store创建函数
export {

View File

@@ -28,7 +28,9 @@ export const useCkChatStore = createPersistStore<CkChatState>(
},
// 获取客服列表
getkfUserList: async () => {
return await kfUserService.findAll();
const state = useCkChatStore.getState();
return state.kfUserList;
// return await kfUserService.findAll();
},
// 异步设置标签列表
asyncCountLables: async (data: ContactGroupByLabel[]) => {

View File

@@ -0,0 +1,78 @@
//消息管理器
import { WebSocketMessage } from "./websocket";
import { getkfUserList, asyncKfUserList } from "@/store/module/ckchat/ckchat";
// 消息处理器类型定义
type MessageHandler = (message: WebSocketMessage) => void;
// 消息处理器映射
const messageHandlers: Record<string, MessageHandler> = {
// 微信账号存活状态响应
CmdRequestWechatAccountsAliveStatusResp: message => {
console.log("微信账号存活状态响应", message);
// 获取客服列表
const kfUserList = getkfUserList();
const wechatAccountsAliveStatus = message.wechatAccountsAliveStatus || {};
// 遍历客服列表,更新存活状态
kfUserList.forEach(kfUser => {
kfUser.isOnline = wechatAccountsAliveStatus[kfUser.id];
});
asyncKfUserList(kfUserList);
},
// 登录响应
CmdSignInResp: message => {
console.log("登录响应", message);
// 在这里添加具体的处理逻辑
},
// 通知消息
CmdNotify: message => {
console.log("通知消息", message);
// 在这里添加具体的处理逻辑
},
// 可以继续添加更多处理器...
};
// 默认处理器
const defaultHandler: MessageHandler = message => {
console.log("未知消息类型", message.cmdType, message);
};
// 注册新的消息处理器
export const registerMessageHandler = (
cmdType: string,
handler: MessageHandler,
) => {
messageHandlers[cmdType] = handler;
};
// 移除消息处理器
export const unregisterMessageHandler = (cmdType: string) => {
delete messageHandlers[cmdType];
};
// 获取所有已注册的消息类型
export const getRegisteredMessageTypes = (): string[] => {
return Object.keys(messageHandlers);
};
// 消息管理核心函数
export const msgManageCore = (message: WebSocketMessage) => {
console.log("获取消息---------------------");
const cmdType = message.cmdType;
if (!cmdType) {
console.warn("消息缺少cmdType字段", message);
return;
}
// 获取对应的处理器,如果没有则使用默认处理器
const handler = messageHandlers[cmdType] || defaultHandler;
try {
handler(message);
} catch (error) {
console.error(`处理消息类型 ${cmdType} 时发生错误:`, error);
}
};

View File

@@ -1,9 +1,9 @@
import { createPersistStore } from "@/store/createPersistStore";
import { Toast } from "antd-mobile";
import { useUserStore } from "./user";
import { useUserStore } from "../user";
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
const { getAccountId } = useCkChatStore.getState();
import { msgManageCore } from "./msgManage";
// WebSocket消息类型
export interface WebSocketMessage {
cmdType?: string;
@@ -102,16 +102,16 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
currentState.status === WebSocketStatus.CONNECTED ||
currentState.status === WebSocketStatus.CONNECTING
) {
console.log("WebSocket已连接或正在连接跳过重复连接", {
currentStatus: currentState.status,
hasWebSocket: !!currentState.ws,
});
// console.log("WebSocket已连接或正在连接跳过重复连接", {
// currentStatus: currentState.status,
// hasWebSocket: !!currentState.ws,
// });
return;
}
// 如果已经有WebSocket实例先断开
if (currentState.ws) {
console.log("断开现有WebSocket连接");
// console.log("断开现有WebSocket连接");
currentState.disconnect();
}
@@ -138,19 +138,19 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
});
// 调试信息:输出配置和环境变量
console.log("WebSocket配置信息:", {
configUrl: fullConfig.url,
envUrl: (import.meta as any).env?.VITE_API_WS_URL,
fullConfig,
params: params.toString(),
});
// console.log("WebSocket配置信息:", {
// configUrl: fullConfig.url,
// envUrl: (import.meta as any).env?.VITE_API_WS_URL,
// fullConfig,
// params: params.toString(),
// });
const wsUrl = fullConfig.url + "?" + params;
console.log("最终WebSocket URL:", wsUrl);
// console.log("最终WebSocket URL:", wsUrl);
// 检查URL是否为localhost如果是则不连接
if (wsUrl.includes("localhost") || wsUrl.includes("127.0.0.1")) {
console.error("WebSocket连接被拦截不允许连接到本地地址", wsUrl);
// console.error("WebSocket连接被拦截不允许连接到本地地址", wsUrl);
Toast.show({
content: "WebSocket连接被拦截不允许连接到本地地址",
position: "top",
@@ -175,9 +175,9 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
set({ ws });
console.log("WebSocket连接创建成功", wsUrl);
// console.log("WebSocket连接创建成功", wsUrl);
} catch (error) {
console.error("WebSocket连接失败:", error);
// console.error("WebSocket连接失败:", error);
set({ status: WebSocketStatus.ERROR });
Toast.show({ content: "WebSocket连接失败", position: "top" });
}
@@ -199,7 +199,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
reconnectAttempts: 0,
});
console.log("WebSocket连接已断开");
// console.log("WebSocket连接已断开");
},
// 发送消息
@@ -220,9 +220,9 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
try {
currentState.ws.send(JSON.stringify(fullMessage));
console.log("消息发送成功:", fullMessage);
// console.log("消息发送成功:", fullMessage);
} catch (error) {
console.error("消息发送失败:", error);
// console.error("消息发送失败:", error);
Toast.show({ content: "消息发送失败", position: "top" });
}
},
@@ -246,9 +246,9 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
try {
currentState.ws.send(JSON.stringify(command));
console.log("命令发送成功:", command);
// console.log("命令发送成功:", command);
} catch (error) {
console.error("命令发送失败:", error);
// console.error("命令发送失败:", error);
Toast.show({ content: "命令发送失败", position: "top" });
}
},
@@ -270,7 +270,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
if (currentState.config) {
// 检查是否允许重连
if (!currentState.config.autoReconnect) {
console.log("自动重连已禁用,不再尝试重连");
// console.log("自动重连已禁用,不再尝试重连");
return;
}
currentState.connect(currentState.config);
@@ -286,7 +286,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
reconnectAttempts: 0,
});
console.log("WebSocket连接成功");
// console.log("WebSocket连接成功");
const { token2 } = useUserStore.getState();
// 发送登录命令
if (currentState.config) {
@@ -305,13 +305,13 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
_handleMessage: (event: MessageEvent) => {
try {
const data = JSON.parse(event.data);
console.log("收到WebSocket消息:", data);
// console.log("收到WebSocket消息:", data);
// 处理特定的通知消息
if (data.cmdType === "CmdNotify") {
// 处理Auth failed通知
if (data.notify === "Auth failed" || data.notify === "Kicked out") {
console.error(`WebSocket ${data.notify},断开连接`);
// console.error(`WebSocket ${data.notify},断开连接`);
Toast.show({
content: `WebSocket ${data.notify},断开连接`,
position: "top",
@@ -347,11 +347,13 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
messages: [...currentState.messages, newMessage],
unreadCount: currentState.unreadCount + 1,
});
//消息处理器
msgManageCore(data);
// 可以在这里添加消息处理逻辑
// 比如播放提示音、显示通知等
} catch (error) {
console.error("解析WebSocket消息失败:", error);
// console.error("解析WebSocket消息失败:", error);
}
},
@@ -359,7 +361,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
_handleClose: (event: CloseEvent) => {
const currentState = get();
console.log("WebSocket连接关闭:", event.code, event.reason);
// console.log("WebSocket连接关闭:", event.code, event.reason);
set({
status: WebSocketStatus.DISCONNECTED,
@@ -372,10 +374,10 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
currentState.reconnectAttempts <
(currentState.config?.maxReconnectAttempts || 5)
) {
console.log("尝试自动重连...");
// console.log("尝试自动重连...");
currentState._startReconnectTimer();
} else if (!currentState.config?.autoReconnect) {
console.log("自动重连已禁用,不再尝试重连");
// console.log("自动重连已禁用,不再尝试重连");
// 重置重连计数
set({ reconnectAttempts: 0 });
}
@@ -383,7 +385,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
// 内部方法:处理连接错误
_handleError: (event: Event) => {
console.error("WebSocket连接错误:", event);
// console.error("WebSocket连接错误:", event);
set({ status: WebSocketStatus.ERROR });
@@ -402,9 +404,9 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
});
const timer = setTimeout(() => {
console.log(
`尝试重连 (${currentState.reconnectAttempts + 1}/${currentState.config?.maxReconnectAttempts})`,
);
// console.log(
// `尝试重连 (${currentState.reconnectAttempts + 1}/${currentState.config?.maxReconnectAttempts})`,
// );
currentState.reconnect();
}, currentState.config?.reconnectInterval || 3000);
@@ -434,10 +436,10 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
onRehydrateStorage: () => state => {
// 页面刷新后,如果之前是连接状态,尝试重新连接
if (state && state.status === WebSocketStatus.CONNECTED && state.config) {
console.log("页面刷新后恢复WebSocket连接", {
persistedConfig: state.config,
currentDefaultConfig: DEFAULT_CONFIG,
});
// console.log("页面刷新后恢复WebSocket连接", {
// persistedConfig: state.config,
// currentDefaultConfig: DEFAULT_CONFIG,
// });
// 使用最新的默认配置,而不是持久化的配置
const freshConfig = {
@@ -448,24 +450,24 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
autoReconnect: state.config.autoReconnect,
};
console.log("使用刷新后的配置重连:", freshConfig);
// console.log("使用刷新后的配置重连:", freshConfig);
// 延迟一下再重连,确保页面完全加载
// 同时检查当前状态,避免重复连接
setTimeout(() => {
// 重新获取最新的状态而不是使用闭包中的state
const currentState = useWebSocketStore.getState();
console.log("页面刷新后检查状态", {
status: currentState.status,
hasWs: !!currentState.ws,
});
// console.log("页面刷新后检查状态", {
// status: currentState.status,
// hasWs: !!currentState.ws,
// });
// 强制重置状态为disconnected因为页面刷新后WebSocket实例已失效
if (
currentState.status === WebSocketStatus.CONNECTED &&
!currentState.ws
) {
console.log("检测到状态不一致重置为disconnected");
// console.log("检测到状态不一致重置为disconnected");
useWebSocketStore.setState({
status: WebSocketStatus.DISCONNECTED,
});
@@ -477,12 +479,12 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
latestState.status === WebSocketStatus.DISCONNECTED ||
latestState.status === WebSocketStatus.ERROR
) {
console.log("页面刷新后开始重连");
// console.log("页面刷新后开始重连");
latestState.connect(freshConfig);
} else {
console.log("WebSocket已连接或正在连接跳过页面刷新重连", {
status: latestState.status,
});
// console.log("WebSocket已连接或正在连接跳过页面刷新重连", {
// status: latestState.status,
// });
}
}, 1000);
}