import type { ChatMessage } from '@/types/api' import type { MessageType, CallStatus } from '@/types/message' /** * WebSocket连接管理 */ export interface WebSocketMessage { request_type?: string clientId?: string data?: ChatMessage } export type MessageHandler = (message: ChatMessage) => void export type SignalHandler = (message: ChatMessage) => void class WebSocketManager { private ws: WebSocket | null = null private clientId: string | null = null private userId: string | null = null private messageHandlers: MessageHandler[] = [] private signalHandlers: SignalHandler[] = [] private reconnectAttempts = 0 private maxReconnectAttempts = 5 private reconnectDelay = 3000 /** * 连接WebSocket */ connect(userId: string): Promise { return new Promise((resolve, reject) => { if (this.ws?.readyState === WebSocket.OPEN) { resolve() return } this.userId = userId const wsUrl = `ws://localhost:12080/ws?user_id=${userId}` try { this.ws = new WebSocket(wsUrl) this.ws.onopen = () => { console.log('WebSocket connected') this.reconnectAttempts = 0 resolve() } this.ws.onmessage = (event) => { try { const payload: WebSocketMessage = JSON.parse(event.data) // 接收clientId if (payload.clientId) { this.clientId = payload.clientId console.log('Received clientId:', this.clientId) } // 处理接收消息 if (payload.request_type === 'receive_message' && payload.data) { this.handleMessage(payload.data) } } catch (error) { console.error('WebSocket message parse error:', error) } } this.ws.onerror = (error) => { console.error('WebSocket error:', error) reject(error) } this.ws.onclose = () => { console.log('WebSocket closed') this.ws = null this.attemptReconnect() } } catch (error) { reject(error) } }) } /** * 断开连接 */ disconnect() { if (this.ws) { this.ws.close() this.ws = null } this.clientId = null this.userId = null this.messageHandlers = [] this.signalHandlers = [] } /** * 获取ClientID */ getClientId(): string | null { return this.clientId } /** * 添加消息处理器 */ onMessage(handler: MessageHandler) { this.messageHandlers.push(handler) } /** * 移除消息处理器 */ offMessage(handler: MessageHandler) { const index = this.messageHandlers.indexOf(handler) if (index > -1) { this.messageHandlers.splice(index, 1) } } /** * 添加信令处理器 */ onSignal(handler: SignalHandler) { this.signalHandlers.push(handler) } /** * 移除信令处理器 */ offSignal(handler: SignalHandler) { const index = this.signalHandlers.indexOf(handler) if (index > -1) { this.signalHandlers.splice(index, 1) } } /** * 处理接收到的消息 */ private handleMessage(message: ChatMessage) { // 信令消息(message_type = 6) if (message.message_type === 6) { this.signalHandlers.forEach(handler => handler(message)) } else { // 普通消息 this.messageHandlers.forEach(handler => handler(message)) } } /** * 尝试重连 */ private attemptReconnect() { if (this.reconnectAttempts >= this.maxReconnectAttempts) { console.error('Max reconnect attempts reached') return } if (!this.userId) { return } this.reconnectAttempts++ console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`) setTimeout(() => { if (this.userId) { this.connect(this.userId).catch(console.error) } }, this.reconnectDelay) } } // 单例 export const wsManager = new WebSocketManager()