fix: socket连接代码优化,耗材增加具体统计弹窗
This commit is contained in:
@@ -1,13 +1,44 @@
|
||||
import { Client } from "@stomp/stompjs";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import qs from "qs";
|
||||
import { useUserStoreHook } from "@/store";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const user = useUserStoreHook()
|
||||
|
||||
export interface ApifoxModel {
|
||||
account: string;
|
||||
/**
|
||||
* 操作类型
|
||||
*/
|
||||
operate_type: string;
|
||||
shop_id: string;
|
||||
/**
|
||||
* 桌码
|
||||
*/
|
||||
table_code?: string;
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
type: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
export type msgType = 'add' | 'reduce' | 'remove' | 'edit' | 'init' | 'cleanup' | 'del' | 'rottable' | 'batch'
|
||||
class WebSocketManager {
|
||||
private client: Client | null = null;
|
||||
private client: WebSocket | null = null;
|
||||
private connected: boolean = false;
|
||||
private shop_id = user.userInfo.shopId ? String(user.userInfo.shopId) : '';
|
||||
private initParams: ApifoxModel = {
|
||||
type: 'manage',
|
||||
account: this.shop_id,
|
||||
operate_type: 'init',
|
||||
table_code: '',
|
||||
shop_id: this.shop_id,
|
||||
};
|
||||
private onMessage: (message: any) => void = function () { };
|
||||
private messageHandlers: Map<string, ((message: string) => void)[]> = new Map();
|
||||
private type: string = 'manage';
|
||||
private reconnectAttempts = 0;
|
||||
private maxReconnectAttempts = 3; // 自定义最大重试次数
|
||||
private reconnectDelay = 5000; // 重试延迟(单位:毫秒)
|
||||
|
||||
private timer: any | null = null;
|
||||
// 初始化 WebSocket 客户端
|
||||
setupWebSocket() {
|
||||
const endpoint = import.meta.env.VITE_APP_WS_ENDPOINT;
|
||||
@@ -18,74 +49,112 @@ class WebSocketManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.client && this.client.connected) {
|
||||
if (this.client && this.connected) {
|
||||
console.log("客户端已存在并且连接正常");
|
||||
return this.client;
|
||||
}
|
||||
const url = qs.stringify(this.initParams)
|
||||
this.client = new WebSocket(endpoint + '?' + url);
|
||||
this.client.onopen = () => {
|
||||
this.connected = true;
|
||||
console.log("WebSocket 连接已建立");
|
||||
// ElNotification.success('WebSocket 连接已建立')
|
||||
this.sendMessage(this.initParams)
|
||||
clearTimeout(this.timer)
|
||||
this.timer = setInterval(() => {
|
||||
this.sendMessage({ "type": "ping_interval" })
|
||||
}, 1000 * 10);
|
||||
};
|
||||
this.client.onclose = () => {
|
||||
clearTimeout(this.timer)
|
||||
if (!this.connected) {
|
||||
// ElMessageBox.alert('WebSocket 连接已断开', 'Title', {
|
||||
// confirmButtonText: '立即重连',
|
||||
// callback: () => {
|
||||
// this.sendMessage(this.initParams)
|
||||
// },
|
||||
// })
|
||||
}
|
||||
this.connected = false;
|
||||
console.log("WebSocket 连接已断开");
|
||||
};
|
||||
this.client.onerror = (error) => {
|
||||
clearTimeout(this.timer)
|
||||
console.error("WebSocket 发生错误:", error);
|
||||
// ElNotification({
|
||||
// title: "提示",
|
||||
// message: "WebSocket 发生错误",
|
||||
// type: "error",
|
||||
// });
|
||||
// ElMessageBox.alert('WebSocket 发生错误', 'Title', {
|
||||
// confirmButtonText: '立即重连',
|
||||
// callback: () => {
|
||||
// this.sendMessage(this.initParams)
|
||||
// },
|
||||
// })
|
||||
};
|
||||
this.client.onmessage = (event) => {
|
||||
const message = event.data;
|
||||
const msg = JSON.parse(message)
|
||||
if (msg && msg.msg_id) {
|
||||
this.onMessageHandler({ msg_id: msg.msg_id })
|
||||
}
|
||||
this.onMessage(msg);
|
||||
};
|
||||
}
|
||||
|
||||
this.client = new Client({
|
||||
brokerURL: endpoint,
|
||||
connectHeaders: {
|
||||
Authorization: getToken(),
|
||||
},
|
||||
heartbeatIncoming: 30000,
|
||||
heartbeatOutgoing: 30000,
|
||||
reconnectDelay: 0, // 设置为 0 禁用重连
|
||||
onConnect: () => {
|
||||
console.log(`连接到 WebSocket 服务器: ${endpoint}`);
|
||||
this.reconnectAttempts = 0; // 重置重连计数
|
||||
this.messageHandlers.forEach((handlers, topic) => {
|
||||
handlers.forEach((handler) => {
|
||||
this.subscribeToTopic(topic, handler);
|
||||
});
|
||||
});
|
||||
},
|
||||
onStompError: (frame) => {
|
||||
console.error(`连接错误: ${frame.headers["message"]}`);
|
||||
console.error(`错误详情: ${frame.body}`);
|
||||
},
|
||||
onDisconnect: () => {
|
||||
console.log(`WebSocket 连接已断开: ${endpoint}`);
|
||||
this.reconnectAttempts++;
|
||||
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
console.log(`正在尝试重连... 尝试次数: ${this.reconnectAttempts}`);
|
||||
} else {
|
||||
console.log("重连次数已达上限,停止重连");
|
||||
this.client?.deactivate();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
this.client.activate();
|
||||
// 消息回执
|
||||
public onMessageHandler(data: any) {
|
||||
if (this.client && this.connected) {
|
||||
this.client.send(JSON.stringify({ ...data, type: 'receipt' }));
|
||||
}
|
||||
}
|
||||
|
||||
// 订阅主题
|
||||
public subscribeToTopic(topic: string, onMessage: (message: string) => void) {
|
||||
console.log(`正在订阅主题: ${topic}`);
|
||||
if (!this.client || !this.client.connected) {
|
||||
public subscribeToTopic(initParams: ApifoxModel, onMessage: (message: any) => void) {
|
||||
console.log(`正在订阅主题: `, initParams);
|
||||
this.initParams = { ...this.initParams, ...initParams }
|
||||
if (this.client && this.connected) {
|
||||
this.disconnect();
|
||||
}
|
||||
this.setupWebSocket();
|
||||
this.onMessage = onMessage;
|
||||
}
|
||||
public sendMessage(message: any) {
|
||||
if (!this.client || !this.connected) {
|
||||
ElMessage.error('发送失败,已重新连接,请重新操作')
|
||||
this.disconnect()
|
||||
this.setupWebSocket();
|
||||
return
|
||||
}
|
||||
if (this.client && this.connected) {
|
||||
const msg = JSON.stringify({
|
||||
...this.initParams,
|
||||
...message,
|
||||
})
|
||||
try {
|
||||
this.client.send(msg);
|
||||
|
||||
if (this.messageHandlers.has(topic)) {
|
||||
this.messageHandlers.get(topic)?.push(onMessage);
|
||||
} else {
|
||||
this.messageHandlers.set(topic, [onMessage]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('error')
|
||||
ElMessage.error('发送失败,已重新连接,请重新操作')
|
||||
this.disconnect()
|
||||
this.setupWebSocket();
|
||||
|
||||
if (this.client?.connected) {
|
||||
this.client.subscribe(topic, (message) => {
|
||||
const handlers = this.messageHandlers.get(topic);
|
||||
handlers?.forEach((handler) => handler(message.body));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public canSendMessage() {
|
||||
return this.client && this.connected;
|
||||
}
|
||||
// 断开 WebSocket 连接
|
||||
public disconnect() {
|
||||
if (this.client) {
|
||||
if (this.client && this.connected) {
|
||||
console.log("断开 WebSocket 连接");
|
||||
this.client.deactivate();
|
||||
clearTimeout(this.timer)
|
||||
this.client.close();
|
||||
this.client = null;
|
||||
this.connected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,45 @@
|
||||
import qs from "qs";
|
||||
import { useUserStoreHook } from "@/store";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const user = useUserStoreHook()
|
||||
|
||||
const user = useUserStoreHook();
|
||||
|
||||
export interface ApifoxModel {
|
||||
account: string;
|
||||
/**
|
||||
* 操作类型
|
||||
*/
|
||||
operate_type: string;
|
||||
shop_id: string;
|
||||
/**
|
||||
* 桌码
|
||||
*/
|
||||
table_code?: string;
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
type: string;
|
||||
[property: string]: any;
|
||||
[property: string]: string | number | undefined; // 限制额外属性类型
|
||||
}
|
||||
export type msgType = 'add' | 'reduce' | 'remove' | 'edit' | 'init' | 'cleanup' | 'del' | 'rottable' | 'batch'
|
||||
|
||||
export type msgType = 'add' | 'reduce' | 'remove' | 'edit' | 'init' | 'cleanup' | 'del' | 'rottable' | 'batch';
|
||||
|
||||
class WebSocketManager {
|
||||
private client: WebSocket | null = null;
|
||||
private connected: boolean = false;
|
||||
private shop_id = user.userInfo.shopId ? String(user.userInfo.shopId) : '';
|
||||
private initParams: ApifoxModel = {
|
||||
type: 'manage',
|
||||
account: this.shop_id,
|
||||
account: this.shop_id || '', // 提供默认值
|
||||
operate_type: 'init',
|
||||
table_code: '',
|
||||
shop_id: this.shop_id,
|
||||
shop_id: this.shop_id || '', // 提供默认值
|
||||
};
|
||||
private onMessage: (message: any) => void = function () { };
|
||||
private onMessage: (message: any) => void = () => { };
|
||||
private messageHandlers: Map<string, ((message: string) => void)[]> = new Map();
|
||||
private type: string = 'manage';
|
||||
private reconnectAttempts = 0;
|
||||
private maxReconnectAttempts = 3; // 自定义最大重试次数
|
||||
private reconnectDelay = 5000; // 重试延迟(单位:毫秒)
|
||||
private timer: any | null = null;
|
||||
|
||||
// 初始化 WebSocket 客户端
|
||||
setupWebSocket() {
|
||||
const endpoint = import.meta.env.VITE_APP_WS_ENDPOINT;
|
||||
|
||||
// 如果没有配置 WebSocket 端点或显式关闭,直接返回
|
||||
if (!endpoint) {
|
||||
console.log("WebSocket 已被禁用,如需打开请在配置文件中配置 VITE_APP_WS_ENDPOINT");
|
||||
console.warn("WebSocket 已被禁用,请在配置文件中配置 VITE_APP_WS_ENDPOINT");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,60 +47,49 @@ class WebSocketManager {
|
||||
console.log("客户端已存在并且连接正常");
|
||||
return this.client;
|
||||
}
|
||||
const url = qs.stringify(this.initParams)
|
||||
|
||||
const url = qs.stringify(this.initParams);
|
||||
this.client = new WebSocket(endpoint + '?' + url);
|
||||
|
||||
this.client.onopen = () => {
|
||||
this.connected = true;
|
||||
console.log("WebSocket 连接已建立");
|
||||
// ElNotification.success('WebSocket 连接已建立')
|
||||
this.sendMessage(this.initParams)
|
||||
clearTimeout(this.timer)
|
||||
this.sendMessage(this.initParams);
|
||||
this.clearTimer();
|
||||
this.timer = setInterval(() => {
|
||||
this.sendMessage({ "type": "ping_interval" })
|
||||
this.sendMessage({ type: "ping_interval" });
|
||||
}, 1000 * 10);
|
||||
};
|
||||
|
||||
this.client.onclose = () => {
|
||||
clearTimeout(this.timer)
|
||||
if (!this.connected) {
|
||||
// ElMessageBox.alert('WebSocket 连接已断开', 'Title', {
|
||||
// confirmButtonText: '立即重连',
|
||||
// callback: () => {
|
||||
// this.sendMessage(this.initParams)
|
||||
// },
|
||||
// })
|
||||
}
|
||||
this.clearTimer();
|
||||
this.connected = false;
|
||||
console.log("WebSocket 连接已断开");
|
||||
this.reconnect(); // 自动重连
|
||||
};
|
||||
this.client.onerror = (error) => {
|
||||
clearTimeout(this.timer)
|
||||
this.connected = false;
|
||||
|
||||
this.client.onerror = (error: Event) => {
|
||||
this.clearTimer();
|
||||
console.error("WebSocket 发生错误:", error);
|
||||
// ElNotification({
|
||||
// title: "提示",
|
||||
// message: "WebSocket 发生错误",
|
||||
// type: "error",
|
||||
// });
|
||||
// ElMessageBox.alert('WebSocket 发生错误', 'Title', {
|
||||
// confirmButtonText: '立即重连',
|
||||
// callback: () => {
|
||||
// this.sendMessage(this.initParams)
|
||||
// },
|
||||
// })
|
||||
this.reconnect(); // 自动重连
|
||||
};
|
||||
this.client.onmessage = (event) => {
|
||||
const message = event.data;
|
||||
const msg = JSON.parse(message)
|
||||
if (msg && msg.msg_id) {
|
||||
this.onMessageHandler({ msg_id: msg.msg_id })
|
||||
|
||||
this.client.onmessage = (event: MessageEvent) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
if (message && message.msg_id) {
|
||||
this.onMessageHandler({ msg_id: message.msg_id });
|
||||
}
|
||||
this.onMessage(message);
|
||||
} catch (e) {
|
||||
console.error("消息解析失败:", e);
|
||||
}
|
||||
this.onMessage(msg);
|
||||
};
|
||||
}
|
||||
|
||||
// 消息回执
|
||||
public onMessageHandler(data: any) {
|
||||
if (this.client) {
|
||||
if (this.client && this.connected) {
|
||||
this.client.send(JSON.stringify({ ...data, type: 'receipt' }));
|
||||
}
|
||||
}
|
||||
@@ -114,49 +97,64 @@ class WebSocketManager {
|
||||
// 订阅主题
|
||||
public subscribeToTopic(initParams: ApifoxModel, onMessage: (message: any) => void) {
|
||||
console.log(`正在订阅主题: `, initParams);
|
||||
this.initParams = { ...this.initParams, ...initParams }
|
||||
if (this.client && this.connected) {
|
||||
this.disconnect();
|
||||
}
|
||||
this.initParams = { ...this.initParams, ...initParams };
|
||||
this.disconnect();
|
||||
this.setupWebSocket();
|
||||
this.onMessage = onMessage;
|
||||
}
|
||||
|
||||
public sendMessage(message: any) {
|
||||
if (!this.client || !this.connected) {
|
||||
ElMessage.error('发送失败,已重新连接,请重新操作')
|
||||
this.disconnect()
|
||||
this.setupWebSocket();
|
||||
return
|
||||
// ElMessage.error('发送失败,已重新连接,请重新操作');
|
||||
this.reconnect();
|
||||
return;
|
||||
}
|
||||
if (this.client && this.connected) {
|
||||
const msg = JSON.stringify({
|
||||
...this.initParams,
|
||||
...message,
|
||||
})
|
||||
try {
|
||||
this.client.send(msg);
|
||||
|
||||
} catch (error) {
|
||||
console.log('error')
|
||||
ElMessage.error('发送失败')
|
||||
this.disconnect()
|
||||
this.setupWebSocket();
|
||||
|
||||
}
|
||||
const msg = JSON.stringify({ ...this.initParams, ...message });
|
||||
try {
|
||||
this.client?.send(msg);
|
||||
} catch (error) {
|
||||
console.error("发送消息失败:", error);
|
||||
// ElMessage.error('发送失败,已重新连接,请重新操作');
|
||||
this.reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public canSendMessage() {
|
||||
return this.client && this.connected;
|
||||
}
|
||||
|
||||
// 断开 WebSocket 连接
|
||||
public disconnect() {
|
||||
if (this.client) {
|
||||
if (this.client && this.connected) {
|
||||
console.log("断开 WebSocket 连接");
|
||||
this.clearTimer();
|
||||
this.client.close();
|
||||
this.client = null;
|
||||
this.connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 自动重连机制
|
||||
private reconnect() {
|
||||
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
this.reconnectAttempts++;
|
||||
console.log(`尝试第 ${this.reconnectAttempts} 次重连...`);
|
||||
setTimeout(() => {
|
||||
this.setupWebSocket();
|
||||
}, this.reconnectDelay);
|
||||
} else {
|
||||
console.error("达到最大重连次数,停止重连");
|
||||
}
|
||||
}
|
||||
|
||||
// 清除定时器
|
||||
private clearTimer() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new WebSocketManager();
|
||||
export default new WebSocketManager();
|
||||
Reference in New Issue
Block a user