/** * WebSocket 修复验证测试脚本 * * 这个脚本模拟了我们在 living.vue 中所做的修复, * 用于验证修复逻辑的正确性 */ // 模拟 uni-app 的 WebSocket API const mockUniApp = { connectSocket: (options) => { console.log('🔌 模拟连接 WebSocket:', options.url); // 模拟 socketTask 对象 const socketTask = { readyState: 0, // CONNECTING onOpen: null, onClose: null, onError: null, onMessage: null, send: (data) => { if (socketTask.readyState === 1) { console.log('📤 发送消息:', data.data); return Promise.resolve(); } else { console.log('❌ 连接未就绪,无法发送消息'); return Promise.reject(new Error('WebSocket not ready')); } }, close: () => { socketTask.readyState = 3; // CLOSED console.log('🔌 WebSocket 连接已关闭'); } }; // 模拟连接过程 setTimeout(() => { socketTask.readyState = 1; // OPEN if (socketTask.onOpen) { console.log('✅ WebSocket 连接成功'); socketTask.onOpen(); } }, 1000); return socketTask; } }; // 模拟 living.vue 中的相关状态和方法 class MockLivingComponent { constructor() { this.socket = null; this.isSocketOpen = false; this.isConnecting = false; this.isSending = false; this.retryCount = 0; this.maxRetries = 3; this.liveId = 'test_live_123'; this.userData = { userId: 'user_123', nickname: 'TestUser' }; } // 修复后的 initSocket 方法 initSocket() { console.log('\n🚀 开始初始化 WebSocket 连接...'); if (this.isConnecting) { console.log('⚠️ 正在连接中,跳过重复连接'); return; } this.isConnecting = true; this.isSocketOpen = false; const socketTask = mockUniApp.connectSocket({ url: `wss://example.com/websocket?liveId=${this.liveId}` }); // 🔧 修复:立即赋值 socket,而不是等到 onOpen this.socket = socketTask; console.log('✅ socket 实例已赋值'); socketTask.onOpen = () => { console.log('📡 WebSocket onOpen 事件触发'); this.isConnecting = false; this.isSocketOpen = true; this.retryCount = 0; console.log('🎉 WebSocket 连接建立完成'); }; socketTask.onClose = () => { console.log('🔌 WebSocket onClose 事件触发'); this.isSocketOpen = false; this.isConnecting = false; }; socketTask.onError = (error) => { console.log('❌ WebSocket onError 事件触发:', error); this.isSocketOpen = false; this.isConnecting = false; }; } // 修复后的 isSocketAvailable 方法 isSocketAvailable() { const hasSocket = !!this.socket; const isOpen = this.isSocketOpen; const readyState = this.socket ? this.socket.readyState : -1; console.log('🔍 检查 WebSocket 状态:', { hasSocket, isOpen, readyState, readyStateText: this.getReadyStateText(readyState) }); return hasSocket && isOpen && this.socket.readyState === 1; } getReadyStateText(state) { const states = { 0: 'CONNECTING', 1: 'OPEN', 2: 'CLOSING', 3: 'CLOSED', '-1': 'UNDEFINED' }; return states[state] || 'UNKNOWN'; } // 修复后的 sendMsg 方法(简化版) async sendMsg(message) { console.log(`\n📝 尝试发送消息: "${message}"`); if (this.isSending) { console.log('⚠️ 正在发送中,防止重复发送'); return; } if (!message || message.trim() === '') { console.log('❌ 消息内容为空'); return; } if (!this.liveId || !this.userData) { console.log('❌ 缺少必要参数 liveId 或 userData'); return; } this.isSending = true; try { // 检查连接状态 if (!this.isSocketAvailable()) { console.log('⚠️ WebSocket 连接不可用'); if (this.isConnecting) { console.log('⏳ 正在连接中,等待连接完成...'); // 在实际应用中,这里会等待连接完成 await this.waitForConnection(); } else { console.log('🔄 尝试重新连接...'); this.initSocket(); await this.waitForConnection(); } } // 再次检查连接状态 if (!this.isSocketAvailable()) { throw new Error('WebSocket 连接失败'); } // 发送消息 const messageData = { type: 'message', content: message, liveId: this.liveId, user: this.userData, timestamp: Date.now() }; await this.socket.send({ data: JSON.stringify(messageData) }); console.log('✅ 消息发送成功'); } catch (error) { console.log('❌ 消息发送失败:', error.message); if (this.retryCount < this.maxRetries) { this.retryCount++; console.log(`🔄 准备重试 (${this.retryCount}/${this.maxRetries})`); setTimeout(() => { this.sendMsg(message); }, 800); } else { console.log('💥 重试次数用尽,发送失败'); } } finally { this.isSending = false; } } // 等待连接完成的辅助方法 waitForConnection(timeout = 5000) { return new Promise((resolve, reject) => { const startTime = Date.now(); const checkConnection = () => { if (this.isSocketAvailable()) { resolve(); } else if (Date.now() - startTime > timeout) { reject(new Error('连接超时')); } else { setTimeout(checkConnection, 100); } }; checkConnection(); }); } } // 运行测试 async function runTest() { console.log('🧪 开始 WebSocket 修复验证测试\n'); const component = new MockLivingComponent(); // 测试场景1:在连接建立前尝试发送消息 console.log('📋 测试场景1:连接建立前发送消息'); component.sendMsg('Hello, this is a test message!'); // 等待一段时间让连接建立 setTimeout(() => { console.log('\n📋 测试场景2:连接建立后发送消息'); component.sendMsg('Second message after connection established'); }, 2000); // 测试连续发送 setTimeout(() => { console.log('\n📋 测试场景3:连续发送多条消息'); component.sendMsg('Message 1'); component.sendMsg('Message 2'); component.sendMsg('Message 3'); }, 3000); } // 启动测试 runTest(); console.log(` 📊 测试说明: ============= 1. 这个测试模拟了我们在 living.vue 中所做的关键修复 2. 主要验证点: - socket 实例在 connectSocket 后立即可用 - isSocketAvailable 方法能正确判断连接状态 - sendMsg 方法在连接未就绪时能正确处理 - 防重复发送机制正常工作 - 重试机制正常工作 🔧 关键修复点: ============== - 将 this.socket = socketTask 从 onOpen 事件中提前到 connectSocket 之后 - 增强了 isSocketAvailable 方法的状态检查 - 优化了 sendMsg 方法的错误处理和重试逻辑 `);