# 问题修复:批量发车超时 - 使用统一通信机制 v3.9.7 ## 🚀 概述 **问题**: - ✅ 游戏功能模块单独测试:**成功且非常快** - ❌ 批量自动化测试:**超时(20秒)** **用户反馈**: > "单独测试是成功的,而且查询的非常快" **根本原因**: - 批量自动化和游戏功能模块使用了**不同的通信机制** - 批量自动化复用 `client` 对象,在等待和执行期间 `client` 可能失效 - 导致后续命令的 Promise 永远不会被 resolve --- ## 🔍 问题分析 ### 之前的实现(v3.9.6及之前) #### 游戏功能模块(成功✅) ```javascript // CarManagement.vue const response = await tokenStore.sendMessageAsync( tokenId, 'car_getrolecar', {}, 10000 ) ``` **特点**: - ✅ 每次发送时获取最新的 `client` - ✅ 使用响应式连接对象 `wsConnections.value[tokenId]` - ✅ 简单可靠 --- #### 批量自动化(失败❌) ```javascript // batchTaskStore.js (v3.9.6) const client = await ensureConnection(tokenId) // 获取一次 await new Promise(resolve => setTimeout(resolve, 2000)) // 等待2秒 // 后续多次使用这个 client await client.sendWithPromise('car_getrolecar', {}, 20000) // ❌ 可能失效 await client.sendWithPromise('car_refresh', { carId }, 5000) // ❌ 可能失效 await client.sendWithPromise('car_claim', { carId }, 5000) // ❌ 可能失效 await client.sendWithPromise('car_send', { carId }, 5000) // ❌ 可能失效 ``` **问题**: - ❌ 一次性获取 `client` 后长时间复用 - ❌ 在等待期间(2秒)和执行期间,`client` 可能失效 - ❌ 使用非响应式连接对象 `tokenStore.wsConnections[tokenId]` --- ### 为什么 client 会失效? #### 原因1:等待期间连接被替换 ```javascript // 时间点 T0: 获取 client const client = await ensureConnection(tokenId) // 时间点 T0 → T2: 等待2秒 await new Promise(resolve => setTimeout(resolve, 2000)) // 时间点 T2: client 可能已经失效 // - 连接可能被重置 // - tokenStore.reconnectWebSocket 可能创建了新的 client // - 旧的 client 引用失效 await client.sendWithPromise('car_getrolecar', {}, 20000) // ❌ 超时 ``` #### 原因2:Promise 管理器状态不一致 - WebSocket client 内部有 Promise 管理器 - 如果连接重置,Promise 管理器也会重置 - 旧的 Promise 永远不会被 resolve #### 原因3:事件监听器失效 - WebSocket client 依赖 `onmessage` 事件 - 连接重置后,旧的事件监听器失效 - 新消息不会触发旧 client 的 Promise resolve --- ## 🛠️ 解决方案 v3.9.7 ### 核心改进:统一使用 `tokenStore.sendMessageAsync` **不再复用 `client` 对象,每次发送时都获取最新的 `client`** --- ### 修改详情 #### 修改1:查询车辆(第1152行) ```diff - const queryResponse = await client.sendWithPromise('car_getrolecar', {}, 20000) + const queryResponse = await tokenStore.sendMessageAsync(tokenId, 'car_getrolecar', {}, 20000) ``` #### 修改2:刷新车辆(第1200行) ```diff - await client.sendWithPromise('car_refresh', { carId: carId }, 5000) + await tokenStore.sendMessageAsync(tokenId, 'car_refresh', { carId: carId }, 5000) ``` #### 修改3:刷新后重新查询(第1227行) ```diff - const reQueryResponse = await client.sendWithPromise('car_getrolecar', {}, 20000) + const reQueryResponse = await tokenStore.sendMessageAsync(tokenId, 'car_getrolecar', {}, 20000) ``` #### 修改4:收获车辆(第1268行) ```diff - await client.sendWithPromise('car_claim', { carId: carId }, 5000) + await tokenStore.sendMessageAsync(tokenId, 'car_claim', { carId: carId }, 5000) ``` #### 修改5:发送前最后查询(第1298行) ```diff - const finalQueryResponse = await client.sendWithPromise('car_getrolecar', {}, 20000) + const finalQueryResponse = await tokenStore.sendMessageAsync(tokenId, 'car_getrolecar', {}, 20000) ``` #### 修改6:发送车辆(第1311行) ```diff - await client.sendWithPromise('car_send', { carId, helperId: 0, text: "" }, 5000) + await tokenStore.sendMessageAsync(tokenId, 'car_send', { carId, helperId: 0, text: "" }, 5000) ``` --- ## ✅ 优势 ### 1. 统一通信机制 - ✅ 批量自动化与游戏功能模块使用**相同的通信机制** - ✅ 代码一致性和可维护性大幅提升 ### 2. 每次获取最新 client - ✅ 每次发送命令时都通过 `wsConnections.value[tokenId]` 获取最新的 `client` - ✅ 避免 `client` 对象失效问题 ### 3. 使用响应式状态 - ✅ `wsConnections.value[tokenId]` 是响应式的 - ✅ 总是获取到最新的连接状态 ### 4. 简单可靠 - ✅ 逻辑更简单清晰 - ✅ 与游戏功能模块保持一致 - ✅ 避免复杂的 client 管理 --- ## 📊 预期效果 ### v3.9.6(修改前) ``` ✅ WebSocket连接成功 ⏳ 等待连接稳定... (2秒) 📤 发送消息: car_getrolecar {} 💓 心跳消息... (不断收发) ❌ 20秒后超时,没有收到 car_getrolecarresp ``` **问题**:client 对象在等待期间失效 --- ### v3.9.7(修改后) ``` ✅ WebSocket连接成功 ⏳ 等待连接稳定... (2秒) 📤 发送消息: car_getrolecar {} ✅ 收到响应: car_getrolecarresp (1-2秒内) ← 预期快速成功 ✅ [token_xxx] 查询到 4 辆车 ``` **改进**:每次发送都获取最新的 client,避免失效 --- ## 🧪 验证步骤 ### 1. 重启开发服务器 ```bash # 在项目根目录 npm run dev ``` ### 2. 批量测试 1. 打开批量自动化面板 2. 选择**2个账号**(第2个账号待发车状态) 3. 只勾选**"发车"**任务 4. 点击"开始执行" ### 3. 观察结果 #### 期望结果(成功✅) ``` 🎯 开始执行 Token: 805服-0-xxx ✅ WebSocket连接成功 ⏳ 等待连接稳定... 📌 执行任务 [1/1]: sendCar 🚗 [token_xxx] 开始查询俱乐部车辆... ✅ [token_xxx] 查询到 4 辆车 ← 应该1-2秒内完成! 🔄 [token_xxx] 开始批量刷新车辆... ✅ [token_xxx] 刷新车辆成功: carId 🎁 [token_xxx] 开始批量收获... ✅ [token_xxx] 收获车辆成功: carId 🚀 [token_xxx] 开始批量发送... ✅ [token_xxx] 发送车辆成功: carId ✅ Token完成: 805服-0-xxx ⏳ Token token_xxx 将在 3.0秒 后建立连接 ← 串行执行 🎯 开始执行 Token: 805服-1-xxx ✅ WebSocket连接成功 ⏳ 等待连接稳定... 📌 执行任务 [1/1]: sendCar 🚗 [token_xxx] 开始查询俱乐部车辆... ✅ [token_xxx] 查询到 4 辆车 ← 应该1-2秒内完成! ✅ Token完成: 805服-1-xxx 📊 统计信息: {total: 2, success: 2, failed: 0} ✅ ``` **关键指标**: - ✅ 查询车辆应该在1-2秒内完成(而不是20秒超时) - ✅ 每个步骤都能快速响应 - ✅ 整体流程顺畅 --- #### 如果仍然失败(unlikely) 如果修改后仍然超时,说明问题更深层: 1. 可能是服务器端限制 2. 可能需要增加账号间隔(5-10秒) 3. 可能需要检查网络环境 但根据分析,**v3.9.7应该能解决问题** ✅ --- ## 📝 文件修改清单 ### 修改文件 1. ✅ `src/stores/batchTaskStore.js` - 第1152行:查询车辆 - 第1200行:刷新车辆 - 第1227行:刷新后重新查询 - 第1268行:收获车辆 - 第1298行:发送前最后查询 - 第1311行:发送车辆 ### 新增文档 1. ✅ `MD说明/批量自动化发车流程分析v3.9.6.md` - 流程分析文档 2. ✅ `MD说明/问题修复-批量发车超时使用统一通信机制v3.9.7.md` - 本文档 --- ## 🔄 版本信息 - **版本号**:v3.9.7 - **修复日期**:2025-10-08 - **影响范围**:批量自动化 - 发车任务 - **向后兼容**:✅ 完全兼容 - **破坏性变更**:❌ 无 --- ## 💡 技术要点 ### tokenStore.sendMessageAsync 内部实现 ```javascript // src/stores/tokenStore.js 第1414-1430行 const sendMessageWithPromise = async (tokenId, cmd, params = {}, timeout = 1000) => { // 1. 获取最新的连接对象(响应式) const connection = wsConnections.value[tokenId] // 2. 检查连接状态 if (!connection || connection.status !== 'connected') { return Promise.reject(new Error(`WebSocket未连接 [${tokenId}]`)) } // 3. 获取最新的 client const client = connection.client if (!client) { return Promise.reject(new Error(`WebSocket客户端不存在 [${tokenId}]`)) } // 4. 发送命令 try { return await client.sendWithPromise(cmd, params, timeout) } catch (error) { return Promise.reject(error) } } ``` **关键优势**: - ✅ 每次调用都重新获取 `connection` 和 `client` - ✅ 使用 `wsConnections.value`(响应式) - ✅ 检查 `connection.status === 'connected'` - ✅ 确保 `client` 总是最新的 --- ## 🎯 总结 ### 问题本质 - **批量自动化复用 `client` 对象** - **在等待和执行期间,`client` 可能失效** - **导致命令的 Promise 永远不会被 resolve** ### 解决方案 - **统一使用 `tokenStore.sendMessageAsync`** - **每次发送都获取最新的 `client`** - **与游戏功能模块保持一致** ### 预期结果 - ✅ 批量发车应该和单独测试一样**快速成功** - ✅ 查询车辆应该在1-2秒内完成 - ✅ 整体流程顺畅可靠 --- ## 🚀 下一步 1. **重启开发服务器** 2. **批量测试2个账号** 3. **观察是否快速成功** 4. **享受批量发车的便利!** 🎉 如果测试成功,说明问题已完美解决! ✅