Files
xyzw_web_helper/MD说明文件夹/紧急修复-连接池账号混乱问题v3.13.3.md
2025-10-17 20:56:50 +08:00

281 lines
8.4 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.13.3
## 问题描述
**症状:**
- 开启连接池模式100并发 + 连接池大小20单个token任务执行非常慢
- 大量任务超时
- "发车失败 WebSocket未连接" 错误
- "消息处理跳过" 警告
- 感觉指令没有成功发送
**根本原因:**
在 v3.13.0 ~ v3.13.2 版本中,连接池的设计存在**致命缺陷**
```
❌ 错误的设计:
Token A 创建连接 → 执行完任务 → 释放连接
Token B 获取连接 → 复用 Token A 的连接 → 用 Token A 的账号执行 Token B 的任务 ❌
```
**问题详解:**
1. 每个 WebSocket 连接在创建时会使用特定 token 的 `roleToken` 进行认证
2. 这个连接会绑定到该 token 对应的游戏账号
3. 当我们把 Token A 的连接复用给 Token B 使用时:
- Token B 发送的指令实际上是以 Token A 的身份发送的
- 服务器拒绝请求(账号不匹配)
- 导致 "WebSocket未连接"、超时、指令无效等错误
## 修复方案
**正确的设计 (v3.13.3)**
```
✅ 修复后:
连接池大小 = 20同时存在的最大连接数
Token 1-20立即创建连接执行任务
Token 21 等待 Token 1-20 中任何一个完成 → 创建自己的连接 → 执行任务
Token 22 等待下一个名额 → 创建自己的连接 → 执行任务
...
Token 100 等待名额 → 创建自己的连接 → 执行任务
```
**核心改动:**
1. **每个 token 使用自己的连接**(不复用给其他 token
2. **连接池只限制同时存在的连接数量**
3. **通过排队机制突破浏览器连接数限制**
## 代码修改
### 1. WebSocketPool.js
#### 修改前 (v3.13.2)
```javascript
async acquire(tokenId) {
// 方式1复用空闲连接 ❌
if (this.availableConnections.length > 0) {
const existingTokenId = this.availableConnections.shift()
const connection = this.connections.get(existingTokenId)
// 把 existingTokenId 的连接给 tokenId 使用
connection.currentUser = tokenId // ❌ 账号混乱的根源
return connection.client
}
// 方式2创建新连接
// ...
}
release(tokenId) {
// 把连接放回空闲队列,供其他 token 复用 ❌
this.availableConnections.push(tokenId)
}
```
#### 修改后 (v3.13.3)
```javascript
async acquire(tokenId) {
// 🔹 检查此 token 是否已经有连接
const existing = this.connections.get(tokenId)
if (existing && existing.status === 'connected') {
return existing.client // ✅ 使用自己的连接
}
// 🔹 检查是否达到上限
if (this.connections.size >= this.poolSize) {
return null // 需要等待其他 token 释放名额
}
// 🔹 创建新连接(专属于此 token
const client = await this.reconnectWebSocket(tokenId)
this.connections.set(tokenId, { tokenId, client, status: 'connected' })
return client
}
async release(tokenId) {
// 🔹 关闭此 token 的连接
await this.closeConnection(tokenId)
this.connections.delete(tokenId)
// 🔹 如果有等待的 token允许它创建连接
if (this.waitingQueue.length > 0) {
const waiting = this.waitingQueue.shift()
// 让等待的 token 创建自己的连接
waiting.tryAcquire().then(client => waiting.resolve(client))
}
}
```
### 2. batchTaskStore.js
#### 更新日志和注释
```javascript
// 🔹 步骤1从连接池获取连接
client = await wsPool.acquire(tokenId)
batchLog(`✅ 获取连接成功 (此连接专属于此token)`) // ✅ 明确说明
// 🔹 步骤6释放连接
await wsPool.release(tokenId) // ✅ 关闭此token的连接允许等待队列中的token创建连接
```
## 工作原理对比
### 修改前 (v3.13.2) - 错误设计
```
连接池: [Conn1(TokenA), Conn2(TokenB), ..., Conn20(TokenT)]
TokenU 要执行任务 → 获取 Conn1 → 使用 TokenA 的连接 → ❌ 账号错误
```
### 修改后 (v3.13.3) - 正确设计
```
连接池名额: [20个空位]
Token 1-20: 占用20个名额各自创建自己的连接
Token 21-100: 在队列中等待
Token 5 完成 → 释放名额 → Token 21 获得名额 → 创建自己的连接 ✅
```
## 性能影响
### 优势
**完全避免账号混乱问题**
**突破浏览器连接数限制**(通过排队)
**每个 token 使用正确的账号认证**
**指令能够正确发送和执行**
### 劣势
⚠️ **不能复用连接**(每个 token 需要创建新连接)
⚠️ **创建连接有时间成本**(但避免了错误比速度更重要)
### 性能对比
| 指标 | v3.13.2 (错误设计) | v3.13.3 (正确设计) |
|------|-------------------|-------------------|
| 连接复用 | ✅ 支持(但导致错误) | ❌ 不支持 |
| 账号正确性 | ❌ 会混乱 | ✅ 正确 |
| 任务成功率 | ❌ 低(大量超时) | ✅ 高 |
| 创建连接次数 | 20次 | 100次 |
| 总执行时间 | ❌ 很长(因为错误) | ✅ 正常 |
## 配置建议
### 推荐配置 (100 tokens)
```
✅ 启用连接池模式
✅ 连接池大小: 20
✅ 同时执行数: 5
```
**工作流程:**
1. 前 20 个 token 立即创建连接并排队执行最多5个同时执行任务
2. 当一个 token 完成所有任务后,释放连接名额
3. 第 21 个 token 获得名额,创建自己的连接
4. 依次类推,直到所有 100 个 token 完成
### 性能调优
```javascript
// 🎯 目标100并发稳定执行
// 参数1连接池大小同时存在的最大连接数
连接池大小: 20
说明: 浏览器通常限制每个域名 6-10 个连接
20 是一个保守但稳健的值
// 参数2同时执行数同时发送请求的 token 数量)
同时执行数: 5
说明: 控制请求频率避免服务器拥堵
推荐从 5 开始逐步测试
// 关系:
连接池大小 >= 同时执行数
原因: 正在执行的 token 需要占用连接
```
## 测试验证
### 测试场景
```
Token 数量: 100
连接池大小: 20
同时执行数: 5
任务: 俱乐部签到 + 发车
```
### 预期结果
✅ 每个 token 使用自己的连接
✅ 最多 20 个连接同时存在
✅ 最多 5 个 token 同时执行任务
✅ 任务指令正确发送
✅ 无 "WebSocket未连接" 错误
✅ 无账号混乱问题
### 日志示例
```
🎫 [Token001] 请求连接...
✅ [Token001] 获取连接成功 (此连接专属于此token)
📌 [Token001] 执行任务: 俱乐部签到
✅ [Token001] 任务完成
🔓 [Token001] 释放连接
🔄 [连接池v3.13.3] 释放名额,允许 Token021 创建连接
```
## 版本历史
### v3.13.0 (2025-10-08)
- ✅ 首次引入连接池概念
- ❌ 设计缺陷:复用连接导致账号混乱
### v3.13.1
- ✅ 优化连接池性能
- ❌ 仍存在账号混乱问题
### v3.13.2
- ✅ 引入请求节流
- ❌ 仍存在账号混乱问题
### v3.13.3 (本次修复)
-**修复账号混乱问题**
- ✅ 每个 token 使用自己的连接
- ✅ 连接池只限制数量,不复用连接
- ✅ 通过排队机制突破浏览器限制
## 常见问题
### Q: 为什么不能复用连接?
A: 因为每个 WebSocket 连接在建立时会用特定 token 的 `roleToken` 认证,绑定到特定游戏账号。复用会导致用错误的账号发送指令。
### Q: 这会不会导致创建很多连接?
A: 是的100 个 token 会创建 100 个连接,但**不是同时创建**。通过连接池限制,同时最多存在 20 个连接,其他的排队等待。
### Q: 比 v3.13.2 慢吗?
A: 创建连接有时间成本,但 v3.13.2 因为账号混乱导致大量任务失败和超时实际上更慢。v3.13.3 虽然多了创建连接的时间,但任务成功率高,总体更快。
### Q: 连接池大小应该设置多少?
A: 推荐 15-20。不要设置太大避免浏览器限制也不要太小会导致等待时间过长
### Q: 同时执行数应该设置多少?
A: 推荐 5。这是"同时发送请求的 token 数量",太大会拥堵服务器,太小会降低效率。
## 总结
v3.13.3 是一个**关键修复版本**,解决了 v3.13.0-v3.13.2 中连接池设计的根本缺陷。
**核心改变:**
- ❌ 不再复用连接给其他 token
- ✅ 每个 token 使用自己的连接
- ✅ 连接池只限制同时存在的连接数量
- ✅ 通过排队机制实现高并发
**用户影响:**
- ✅ 100并发任务能够正常执行
- ✅ 无账号混乱问题
- ✅ 指令正确发送
- ✅ 任务成功率显著提升
**升级建议:**
🚨 **强烈建议所有使用连接池模式的用户立即升级到 v3.13.3**