Skip to content

🐛 修复 WebSocket 重连时出现的重复连接问题#228

Merged
A-kirami merged 1 commit into
mainfrom
fix/websocket-duplicate-connections
Mar 24, 2025
Merged

🐛 修复 WebSocket 重连时出现的重复连接问题#228
A-kirami merged 1 commit into
mainfrom
fix/websocket-duplicate-connections

Conversation

@A-kirami

Copy link
Copy Markdown
Owner

这个 PR 带来了什么样的更改?

  • 错误修复
  • 新功能
  • 文档/注释
  • 代码格式
  • 代码重构
  • 测试用例
  • 性能优化
  • 外观样式
  • 项目构建
  • 依赖环境
  • 持续集成/部署
  • 其他,请描述:

这个 PR 是否存在破坏性变更?

  • 是的,并已在 issue #___ 号中获得批准
  • 没有

描述

修复 WebSocket 客户端在服务器反复重启时出现多个重复连接的问题,主要改动:

  • 🛠️ 重连定时器管理:通过 reconnectTimer 变量跟踪定时器,每次重连前清除旧的定时器
  • 🔒 连接状态锁:新增 isConnecting 标志防止并发连接
  • 🧹 资源清理优化
    • stop()autoReconnection() 中主动清理重连定时器
    • 连接前强制断开旧连接 (connect() 中调用 disconnect())

动机和背景

当 WebSocket 服务器反复重启时,客户端会出现以下问题:

  1. 多个 setTimeout 定时器堆积导致重复连接
  2. 未关闭的旧连接与新连接同时存在
  3. 显式停止后残留定时器仍可能触发重连

此 PR 通过规范化连接生命周期管理,确保:

  • 同一时间只有 1 个活跃连接
  • 服务器重启时按固定间隔单次重试
  • 显式停止后完全释放资源

resolve #222

其他信息

检查工作

  • 我对我的代码进行了注释,特别是在难以理解的部分
  • 我的更改需要更新文档,并且已对文档进行了相应的更改
  • 我添加了测试并且已经在本地通过,以证明我的修复补丁或新功能有效
  • 我已检查并确保更改没有与其他打开的 Pull Requests 重复

@A-kirami A-kirami added the bug Something isn't working label Mar 23, 2025
@github-project-automation github-project-automation Bot moved this to 🆕 New in Matcha Project Mar 23, 2025
@sourcery-ai

sourcery-ai Bot commented Mar 23, 2025

Copy link
Copy Markdown

Sourcery 评审员指南

此拉取请求解决了一个问题,即当服务器重复重启时,WebSocket 客户端会创建重复的连接。它引入了一个重新连接计时器、一个连接状态锁和资源清理,以确保一次只有一个活动连接存在,并且在显式停止连接时正确释放资源。

WebSocket 停止的序列图

sequenceDiagram
  participant Client

  Client->>Client: stop()
  Client->>Client: explicitlyClosed = true
  alt reconnectTimer is defined
    Client->>Client: clearTimeout(reconnectTimer)
    Client->>Client: reconnectTimer = undefined
  end
  Client->>Client: disconnect()
Loading

文件级别变更

变更 详情 文件
实现了防止在重新连接尝试期间重复 WebSocket 连接的机制。
  • 引入了 reconnectTimer 来跟踪和清除现有重新连接计时器,然后再启动新连接。
  • 添加了 isConnecting 标志以防止并发连接尝试。
  • 确保在尝试新连接之前断开旧连接。
  • 清理了 stop()autoReconnection() 方法中的重新连接计时器。
src/driver/websocket-client/index.ts

针对关联问题的评估

问题 目标 已解决 说明
#222 手动重启 (Ctrl+C) NoneBot 后,Matcha 客户端应在重新连接间隔内自动重新连接到服务器。
#222 防止 WebSocket 服务器重复重启时出现多个重复连接。

可能关联的问题


提示和命令

与 Sourcery 互动

  • 触发新的审查: 在拉取请求上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub 问题: 要求 Sourcery 从审查评论创建一个问题,方法是回复它。您也可以回复审查评论并使用 @sourcery-ai issue 从中创建一个问题。
  • 生成拉取请求标题: 在拉取请求标题中的任何位置写入 @sourcery-ai 以随时生成标题。您也可以在拉取请求上评论 @sourcery-ai title 以随时(重新)生成标题。
  • 生成拉取请求摘要: 在拉取请求正文中的任何位置写入 @sourcery-ai summary 以随时在您想要的位置生成 PR 摘要。您也可以在拉取请求上评论 @sourcery-ai summary 以随时(重新)生成摘要。
  • 生成评审员指南: 在拉取请求上评论 @sourcery-ai guide 以随时(重新)生成评审员指南。
  • 解决所有 Sourcery 评论: 在拉取请求上评论 @sourcery-ai resolve 以解决所有 Sourcery 评论。如果您已经解决了所有评论并且不想再看到它们,这将非常有用。
  • 驳回所有 Sourcery 审查: 在拉取请求上评论 @sourcery-ai dismiss 以驳回所有现有的 Sourcery 审查。如果您想重新开始新的审查,这将特别有用 - 不要忘记评论 @sourcery-ai review 以触发新的审查!
  • 为问题生成行动计划: 在 issue 上评论 @sourcery-ai plan 以生成行动计划。

自定义您的体验

访问您的 仪表板 以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、评审员指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查说明。
  • 调整其他审查设置。

获得帮助

Original review guide in English

Reviewer's Guide by Sourcery

This pull request addresses an issue where the WebSocket client creates duplicate connections when the server restarts repeatedly. It introduces a reconnection timer, a connection status lock, and resource cleanup to ensure only one active connection exists at a time and that resources are properly released when the connection is explicitly stopped.

Sequence diagram for WebSocket stop

sequenceDiagram
  participant Client

  Client->>Client: stop()
  Client->>Client: explicitlyClosed = true
  alt reconnectTimer is defined
    Client->>Client: clearTimeout(reconnectTimer)
    Client->>Client: reconnectTimer = undefined
  end
  Client->>Client: disconnect()
Loading

File-Level Changes

Change Details Files
Implemented a mechanism to prevent duplicate WebSocket connections during reconnection attempts.
  • Introduced reconnectTimer to track and clear existing reconnection timers before initiating a new connection.
  • Added isConnecting flag to prevent concurrent connection attempts.
  • Ensured that the old connection is disconnected before attempting a new connection.
  • Cleaned up the reconnection timer in stop() and autoReconnection() methods.
src/driver/websocket-client/index.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#222 After a manual restart (Ctrl+C) of NoneBot, the Matcha client should automatically reconnect to the server within a reconnection interval.
#222 Prevent multiple duplicate connections when the WebSocket server restarts repeatedly.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@A-kirami - 我已经查看了你的更改 - 这里有一些反馈:

总体评论

  • 使用 clearInterval 而不是 clearTimeout 并直接将计时器 ID 存储为数字可能会更简洁。
  • 考虑添加一个测试用例,模拟快速服务器重启,以确保修复是稳健的。
以下是我在审查期间查看的内容
  • 🟢 一般问题:一切看起来都很好
  • 🟢 安全性:一切看起来都很好
  • 🟢 测试:一切看起来都很好
  • 🟢 复杂性:一切看起来都很好
  • 🟢 文档:一切看起来都很好

Sourcery 对开源是免费的 - 如果你喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用反馈来改进你的评论。
Original comment in English

Hey @A-kirami - I've reviewed your changes - here's some feedback:

Overall Comments:

  • It might be cleaner to use clearInterval instead of clearTimeout and store the timer ID directly as a number.
  • Consider adding a test case that simulates rapid server restarts to ensure the fix is robust.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions

Copy link
Copy Markdown

📦️ 此 PR 构建的应用已经准备就绪

平台 文件 大小
🐧 linux-amd64 matcha_0.4.6_linux-amd64 162.75 MB
🍎 macos-amd64 matcha_0.4.6_macos-amd64 24.54 MB
🍎 macos-arm64 matcha_0.4.6_macos-arm64 24.16 MB
🪟 windows-amd64 matcha_0.4.6_windows-amd64 22.12 MB

*从提交 97a3fe5 构建

@A-kirami
A-kirami merged commit 471d5a3 into main Mar 24, 2025
@A-kirami
A-kirami deleted the fix/websocket-duplicate-connections branch March 24, 2025 13:09
@github-project-automation github-project-automation Bot moved this from 🆕 New to ✅ Done in Matcha Project Mar 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

BUG: 协议端重启后无法正确自动恢复链接

1 participant