|
@@ -0,0 +1,267 @@
|
|
|
|
|
+/**
|
|
|
|
|
+ * 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 方法的错误处理和重试逻辑
|
|
|
|
|
+`);
|