refactor(websocket): 重构websocket模块并添加消息管理器
- 将websocket模块拆分为多个文件,提高代码可维护性 - 新增msgManage.ts处理不同类型的websocket消息 - 优化消息处理逻辑,减少重复代码 - 更新相关文件引用路径
This commit is contained in:
@@ -4,7 +4,7 @@ import {
|
||||
useWebSocketStore,
|
||||
WebSocketStatus,
|
||||
WebSocketMessage,
|
||||
} from "@/store/module/websocket";
|
||||
} from "@/store/module/websocket/websocket";
|
||||
|
||||
/**
|
||||
* WebSocket使用示例组件
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 链式调用处理异步函数
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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[]) => {
|
||||
|
||||
78
Cunkebao/src/store/module/websocket/msgManage.ts
Normal file
78
Cunkebao/src/store/module/websocket/msgManage.ts
Normal 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);
|
||||
}
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user