diff --git a/frontend/src/utils/webSocketClient.ts b/frontend/src/utils/webSocketClient.ts index fead893..cbd33b8 100644 --- a/frontend/src/utils/webSocketClient.ts +++ b/frontend/src/utils/webSocketClient.ts @@ -2,7 +2,7 @@ * WebSocket客户端服务 * 提供WebSocket连接管理、心跳机制、消息处理等功能 * 集成JWT token解析,支持自动获取用户登录名 - * + * * @author hongawen * @version 2.0 */ @@ -66,7 +66,7 @@ namespace WebSocketMessageTypes { progress?: number; errorInfo?: string; } - + /** * 系数校准相关消息 */ @@ -77,7 +77,7 @@ namespace WebSocketMessageTypes { current?: string; calibrationResult?: boolean; } - + /** * 正式检测相关消息 */ @@ -87,7 +87,7 @@ namespace WebSocketMessageTypes { testResult?: 'success' | 'failed' | 'processing'; testData?: any; } - + /** * 通用响应消息 */ @@ -102,14 +102,14 @@ namespace WebSocketMessageTypes { // 导出类型 // ============================================================================ -export type { - WebSocketMessage, - CallbackFunction, - SocketConfig, +export type { + WebSocketMessage, + CallbackFunction, + SocketConfig, WebSocketMessageTypes }; -export { +export { ConnectionStatus }; @@ -130,7 +130,7 @@ export default class SocketService { * 单例实例 */ private static instance: SocketService | null = null; - + /** * 获取单例实例 * @returns SocketService实例 @@ -150,42 +150,42 @@ export default class SocketService { * WebSocket连接实例 */ private ws: WebSocket | null = null; - + /** * 消息回调函数映射表 */ private callBackMapping: Record> = {}; - + /** * 当前连接状态 */ private connectionStatus: ConnectionStatus = ConnectionStatus.DISCONNECTED; - + /** * 发送消息重试计数器 */ private sendRetryCount: number = 0; - + /** * 连接重试计数器 */ private connectRetryCount: number = 0; - + /** * 心跳Worker实例 */ private heartbeatWorker: Worker | null = null; - + /** * Worker脚本的Blob URL */ private workerBlobUrl: string | null = null; - + /** * 最后一次收到心跳响应的时间戳 */ private lastResponseHeartTime: number = Date.now(); - + /** * WebSocket连接配置 */ @@ -246,18 +246,18 @@ export default class SocketService { public connect(): Promise | void { // 检查浏览器支持 if (!window.WebSocket) { - // console.log('您的浏览器不支持WebSocket'); + // console.log('您的浏览器不支持WebSocket'); return; } // 防止重复连接 if (this.connectionStatus === ConnectionStatus.CONNECTING || this.connected) { - // console.warn('WebSocket已连接或正在连接中'); + // console.warn('WebSocket已连接或正在连接中'); return; } this.connectionStatus = ConnectionStatus.CONNECTING; - + try { this.ws = new WebSocket(this.buildWebSocketUrl()); this.setupEventHandlersLegacy(); @@ -289,7 +289,7 @@ export default class SocketService { } this.connectionStatus = ConnectionStatus.CONNECTING; - + try { this.ws = new WebSocket(this.buildWebSocketUrl()); this.setupEventHandlers(resolve, reject); @@ -311,7 +311,7 @@ export default class SocketService { return; } this.callBackMapping[messageType] = callback; - // console.log(`注册消息处理器: ${messageType}`); + // console.log(`注册消息处理器: ${messageType}`); } /** @@ -349,11 +349,11 @@ export default class SocketService { try { // 重置重试计数 this.sendRetryCount = 0; - + // 尝试发送JSON数据,失败则发送原始数据 const message = typeof data === 'string' ? data : JSON.stringify(data); this.ws.send(message); - + //console.log('发送消息:', message); resolve(); } catch (error) { @@ -368,21 +368,21 @@ export default class SocketService { */ public closeWs(): void { //console.log('正在关闭WebSocket连接...'); - + // 清理心跳 this.clearHeartbeat(); - + // 关闭连接 if (this.ws) { this.ws.close(1000, '主动关闭连接'); this.ws = null; } - + // 更新状态 this.connectionStatus = ConnectionStatus.DISCONNECTED; this.connectRetryCount = 0; this.sendRetryCount = 0; - + //console.log('WebSocket连接已关闭'); } @@ -422,15 +422,15 @@ export default class SocketService { */ private buildWebSocketUrl(): string { const { url } = this.config; - + // 直接从JWT token中获取loginName作为name参数 const loginName = jwtUtil.getLoginName(); - + if (loginName) { const separator = url.includes('?') ? '&' : '?'; return `${url}${separator}name=${encodeURIComponent(loginName)}`; } - + // 如果无法获取loginName,返回原始URL并输出警告 console.warn('无法从JWT token中获取loginName,WebSocket连接可能会失败'); return url; @@ -443,11 +443,11 @@ export default class SocketService { */ private setupEventHandlers(resolve: () => void, reject: (error: Error) => void): void { if (!this.ws) return; - + // 连接成功事件 this.ws.onopen = () => { ElMessage.success("WebSocket连接服务端成功"); - // console.log('WebSocket连接成功'); + // console.log('WebSocket连接成功'); this.connectionStatus = ConnectionStatus.CONNECTED; this.connectRetryCount = 0; this.startHeartbeat(); @@ -459,7 +459,7 @@ export default class SocketService { //console.log('WebSocket连接关闭', event.code, event.reason); this.connectionStatus = ConnectionStatus.DISCONNECTED; this.clearHeartbeat(); - + // 非正常关闭且未超过最大重连次数,尝试重连 if (event.code !== 1000 && this.connectRetryCount < this.config.maxReconnectAttempts!) { this.attemptReconnect(); @@ -485,11 +485,11 @@ export default class SocketService { */ private setupEventHandlersLegacy(): void { if (!this.ws) return; - + // 连接成功事件 this.ws.onopen = () => { ElMessage.success("webSocket连接服务端成功了"); - // console.log('连接服务端成功了'); + // console.log('连接服务端成功了'); this.connectionStatus = ConnectionStatus.CONNECTED; this.connectRetryCount = 0; this.startHeartbeat(); @@ -497,10 +497,10 @@ export default class SocketService { // 连接关闭事件 this.ws.onclose = (event: CloseEvent) => { - // console.log('连接webSocket服务端关闭'); + // console.log('连接webSocket服务端关闭'); this.connectionStatus = ConnectionStatus.DISCONNECTED; this.clearHeartbeat(); - + // 保持原有的重连逻辑(被注释掉的) // this.connectRetryCount++; /* setTimeout(() => { @@ -527,10 +527,10 @@ export default class SocketService { */ private handleMessage(event: MessageEvent): void { // console.log('Received message:', event.data); - + // 心跳响应处理 if (event.data === 'over') { - // console.log(`${new Date().toLocaleTimeString()} - 收到心跳响应`); + // console.log(`${new Date().toLocaleTimeString()} - 收到心跳响应`); this.lastResponseHeartTime = Date.now(); return; } @@ -553,16 +553,16 @@ export default class SocketService { } } else { // 非JSON格式的消息,作为普通文本处理 - // console.log('收到非JSON格式消息:', event.data); + // console.log('收到非JSON格式消息:', event.data); // 可以添加文本消息的处理逻辑 if (this.callBackMapping['text']) { - this.callBackMapping['text']({ - type: 'text', - data: event.data + this.callBackMapping['text']({ + type: 'text', + data: event.data }); } } - + } catch (error) { console.error('消息解析失败:', event.data, error); console.error('消息类型:', typeof event.data); @@ -584,11 +584,11 @@ export default class SocketService { this.connectionStatus = ConnectionStatus.RECONNECTING; this.connectRetryCount++; - + const delay = this.config.reconnectDelay! * this.connectRetryCount; - - // console.log(`尝试第${this.connectRetryCount}次重连,${delay}ms后开始...`); - + + // console.log(`尝试第${this.connectRetryCount}次重连,${delay}ms后开始...`); + setTimeout(() => { try { const result = this.connect(); @@ -627,24 +627,24 @@ export default class SocketService { postMessage('heartbeat'); }, ${this.config.heartbeatInterval}); `; - + this.workerBlobUrl = window.URL.createObjectURL( new Blob([workerScript], { type: 'application/javascript' }) ); - + this.heartbeatWorker = new Worker(this.workerBlobUrl); - + // 心跳Worker消息处理 this.heartbeatWorker.onmessage = (event: MessageEvent) => { this.handleHeartbeatTick(); }; - + // Worker错误处理 this.heartbeatWorker.onerror = (error: ErrorEvent) => { console.error('心跳Worker错误:', error); this.clearHeartbeat(); }; - + } catch (error) { console.error('创建心跳Worker失败:', error); } @@ -657,7 +657,7 @@ export default class SocketService { private handleHeartbeatTick(): void { // 检查是否超时(距离上次收到心跳响应的时间) const timeSinceLastResponse = Date.now() - this.lastResponseHeartTime; - + if (timeSinceLastResponse > this.config.timeout!) { console.error(`WebSocket心跳超时: ${timeSinceLastResponse}ms > ${this.config.timeout}ms`); ElMessage.error("WebSocket连接超时,请检查网络连接!"); @@ -665,7 +665,7 @@ export default class SocketService { this.closeWs(); return; } - + this.sendHeartbeat(); } @@ -674,7 +674,7 @@ export default class SocketService { */ private sendHeartbeat(): void { if (this.connected && this.ws) { - // console.log(`${new Date().toLocaleTimeString()} - 发送心跳消息`); + // console.log(`${new Date().toLocaleTimeString()} - 发送心跳消息`); this.ws.send('alive'); } } @@ -688,7 +688,7 @@ export default class SocketService { this.heartbeatWorker.terminate(); this.heartbeatWorker = null; } - + if (this.workerBlobUrl) { window.URL.revokeObjectURL(this.workerBlobUrl); this.workerBlobUrl = null;