/** * WebSocket工具类 - 酒店客房送餐系统 * 用于实时接收新订单通知和状态变更 */ class HotelWebSocket { constructor() { this.ws = null this.reconnectTimer = null this.heartbeatTimer = null this.isConnected = false this.token = null } /** * 连接WebSocket * @param {string} token - WebSocket认证Token * @param {Function} onMessage - 消息回调 * @param {Function} onError - 错误回调 */ connect(token, onMessage, onError) { if (this.isConnected) { console.warn('WebSocket已连接') return } this.token = token const wsUrl = `ws://127.0.0.1:9529/ws/hotel?token=${token}` try { this.ws = new WebSocket(wsUrl) this.ws.onopen = () => { this.isConnected = true console.log('✅ WebSocket连接成功') this.startHeartbeat() if (onMessage) { this.ws.addEventListener('message', onMessage) } } this.ws.onmessage = (event) => { const message = JSON.parse(event.data) console.log('📨 收到WebSocket消息:', message) // 根据消息类型处理 if (message.type === 'NEW_ORDER') { this.handleNewOrder(message.data) } else if (message.type === 'ORDER_STATUS_CHANGED') { this.handleStatusChange(message.data) } } this.ws.onerror = (error) => { console.error('❌ WebSocket错误:', error) this.isConnected = false if (onError) { onError(error) } } this.ws.onclose = () => { console.log('🔌 WebSocket连接关闭') this.isConnected = false this.stopHeartbeat() this.attemptReconnect(onMessage, onError) } } catch (error) { console.error('WebSocket连接失败:', error) this.attemptReconnect(onMessage, onError) } } /** * 断开连接 */ disconnect() { if (this.ws) { this.ws.close() this.ws = null } this.isConnected = false this.stopHeartbeat() if (this.reconnectTimer) { clearTimeout(this.reconnectTimer) this.reconnectTimer = null } } /** * 发送消息 */ send(data) { if (this.isConnected && this.ws.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify(data)) } else { console.warn('WebSocket未连接,无法发送消息') } } /** * 尝试重连 */ attemptReconnect(onMessage, onError) { if (this.reconnectTimer) { return } console.log('⏳ 3秒后尝试重连...') this.reconnectTimer = setTimeout(() => { this.reconnectTimer = null if (this.token) { this.connect(this.token, onMessage, onError) } }, 3000) } /** * 开始心跳 */ startHeartbeat() { this.heartbeatTimer = setInterval(() => { if (this.isConnected) { this.send({ type: 'PING' }) } }, 30000) // 每30秒发送一次心跳 } /** * 停止心跳 */ stopHeartbeat() { if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer) this.heartbeatTimer = null } } /** * 处理新订单 */ handleNewOrder(order) { console.log('🆕 新订单:', order) // 触发自定义事件,供Vue组件监听 window.dispatchEvent(new CustomEvent('hotel-new-order', { detail: order })) } /** * 处理订单状态变更 */ handleStatusChange(data) { console.log('📊 订单状态变更:', data) window.dispatchEvent(new CustomEvent('hotel-order-status-changed', { detail: data })) } } // 导出单例 export default new HotelWebSocket()