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

8.4 KiB
Raw Blame History

🚨 紧急修复:连接池账号混乱问题 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)

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)

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

更新日志和注释

// 🔹 步骤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 完成

性能调优

// 🎯 目标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