Files
xyzw_web_helper/MD说明文件夹/问题修复-批量发车超时使用统一通信机制v3.9.7.md
2025-10-17 20:56:50 +08:00

343 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 问题修复:批量发车超时 - 使用统一通信机制 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) // ❌ 超时
```
#### 原因2Promise 管理器状态不一致
- 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. **享受批量发车的便利!** 🎉
如果测试成功,说明问题已完美解决! ✅