| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /**
- * 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 方法的错误处理和重试逻辑
- `);
|