lis8.0-vue3/src/utils/webSocket.ts
2026-07-16 18:08:54 +08:00

97 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import emitter from '@/utils/mitt';
type WebSocketInternalOptions = {
fullUrl: string;
reconnectInterval?: number;
};
let websocket: WebSocket | null = null;
let reconnectTimer: any = null;
let isManualClose = false;
/** 初始化WebSocket */
export function initWebSocket(options: WebSocketInternalOptions) {
const { fullUrl, reconnectInterval = 3000 } = options;
// 关闭已有连接
if (websocket) {
websocket.close();
}
if (!('WebSocket' in window)) {
console.error('当前浏览器不支持WebSocket');
return;
}
try {
websocket = new WebSocket(fullUrl);
// 连接成功
websocket.onopen = () => {
clearTimeout(reconnectTimer!);
isManualClose = false;
console.log('WebSocket 连接成功');
};
// 接收消息,自动解析按 msgType 分发事件
websocket.onmessage = (event) => {
try {
const rawMsg = JSON.parse(event.data);
const msgType = rawMsg.msgType;
emitter.emit(msgType, rawMsg);
} catch (err) {
console.error('WebSocket消息解析失败:', err);
}
};
// 连接异常
websocket.onerror = (error) => {
console.error('WebSocket 连接异常:', error);
startReconnect(() => initWebSocket(options), reconnectInterval);
};
// 连接关闭
websocket.onclose = () => {
console.log('WebSocket 连接关闭');
if (!isManualClose) {
startReconnect(() => initWebSocket(options), reconnectInterval);
}
};
} catch (error) {
console.error('WebSocket 创建失败:', error);
startReconnect(() => initWebSocket(options), reconnectInterval);
}
}
/** 发送ws消息 */
export function sendWebSocketMessage(message: any): boolean {
if (websocket && websocket.readyState === WebSocket.OPEN) {
websocket.send(JSON.stringify(message));
return true;
}
console.error('WebSocket未连接,发送失败');
return false;
}
/** 手动关闭ws(登出时调用) */
export function closeWebSocket(): void {
isManualClose = true;
if (reconnectTimer) {
clearTimeout(reconnectTimer);
}
websocket?.close();
websocket = null;
}
/** 获取当前连接状态 */
export function getWebSocketState(): number | null {
return websocket?.readyState || null;
}
// 内部重连私有方法
function startReconnect(connectCallback: () => void, interval: number): void {
if (reconnectTimer) {
clearTimeout(reconnectTimer);
}
reconnectTimer = setTimeout(connectCallback, interval);
}