Conversation
- 客户端/服务端全面移除 Heartbeat* 相关选项与实现,统一采用 .NET 8+ KeepAliveInterval/KeepAliveTimeout 进行协议层 PING/PONG 保活与死链检测 - 新增接收分发队列(ReceiveDispatchQueueCapacity),接收循环与用户回调彻底解耦,慢处理器不再阻塞接收与保活检测,队列满时自动背压 - 服务端支持 MaxMessageSize,超限主动断连,防御内存耗尽 - 优化 SendTextAsync 内存分配,关闭连接增加超时保护,所有 API 保持线程安全 - 客户端/服务端 README、XML 注释、参数校验等文档全面更新,去除应用层心跳说明,推荐协议层保活配置 - 单元测试同步调整,移除 HeartbeatResponseMessage 配置
Contributor
There was a problem hiding this comment.
Pull request overview
EN: Summary
This PR refactors EasilyNET’s WebSocket client/server to fully remove application-level heartbeat messages and rely on .NET 8+ protocol-level keep-alive (PING/PONG) for liveness, while also adding receive/dispatch decoupling and max inbound message size enforcement to improve robustness and prevent memory exhaustion.
Changes:
- Remove Heartbeat* options/logic and switch to
KeepAliveInterval+KeepAliveTimeout(protocol-level) on both client and server. - Introduce a bounded receive-dispatch queue (
ReceiveDispatchQueueCapacity) to decouple receive loops from user callbacks with backpressure. - Add/strengthen max message size handling (server closes on oversize) and update docs/tests accordingly.
EN: Key issues
- The sample
TestModeflag is effectively forced totrueand will run the background test service unconditionally. ReceiveDispatchQueueCapacityis used to construct a bounded channel but lacks an explicit validation path on the server side, which can lead to confusing runtime exceptions.WebSocketClientOptionsXML docs describe keep-alive behavior as sending “PONG” when interval is set alone; this is misleading and should be corrected.
EN: Suggested changes
- Restore
TestModeto default-off (or gate it via configuration / compilation symbol). - Add explicit validation for
ReceiveDispatchQueueCapacitynear channel creation with a clear exception. - Correct XML docs to describe periodic PING frames when only
KeepAliveIntervalis set.
中文:总结
该 PR 对 EasilyNET 的 WebSocket 客户端/服务端进行了统一升级:彻底移除应用层 Heartbeat(业务 ping/pong 消息),改为使用 .NET 8+ 提供的协议层 KeepAlive(PING/PONG)实现保活与死链检测;同时通过接收-分发队列解耦,避免慢处理器阻塞接收循环,并加入/完善 MaxMessageSize 以防止内存耗尽攻击;文档与测试也同步更新。
变更点:
- 移除 Heartbeat* 相关配置与实现,统一使用
KeepAliveInterval+KeepAliveTimeout。 - 新增
ReceiveDispatchQueueCapacity,接收循环与用户回调解耦,队列满时背压。 - 服务端超限主动断连(
MessageTooBig),并同步更新 README/XML 注释/单测。
中文:主要问题
- sample 里的
TestMode => !false等价于永远开启测试模式,会导致后台测试服务在任何环境都执行。 - 服务端侧
ReceiveDispatchQueueCapacity缺少显式校验,配置为 0/负数会在运行时抛出不直观异常。 WebSocketClientOptions注释对 KeepAliveInterval 单独配置时的行为描述为 “PONG”,易误导使用者。
中文:修改建议
- 将 sample 的测试模式恢复为默认关闭,或改为配置开关/编译条件控制。
- 在服务端
WebSocketSession构造处对ReceiveDispatchQueueCapacity做明确校验并抛出清晰异常信息。 - 修正注释为:仅设置
KeepAliveInterval时运行时周期性发送 PING,但不会因超时中止连接。
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/EasilyNET.Test.Unit/WebSocket/ManagedWebSocketClientTest.cs | Update tests to remove HeartbeatResponseMessage usage. |
| test/EasilyNET.Test.Unit/WebSocket/ManagedWebSocketClientMaxMessageSizeTest.cs | Adjust max-message-size tests after heartbeat removal. |
| src/EasilyNET.WebCore/WebSocket/WebSocketSessionOptions.cs | Replace heartbeat options with MaxMessageSize, receive-dispatch queue, and keep-alive options. |
| src/EasilyNET.WebCore/WebSocket/WebSocketSession.cs | Add receive/dispatch decoupling, max-size checks, close timeout handling, and send allocation tweaks. |
| src/EasilyNET.WebCore/WebSocket/README.md | Rewrite docs to reflect protocol-level keep-alive and new session semantics. |
| src/EasilyNET.WebCore/Middleware/WebSocketMiddleware.cs | Pass KeepAliveInterval/Timeout via WebSocketAcceptContext. |
| src/EasilyNET.Core/WebSocket/WebSocketClientOptions.cs | Remove heartbeat options; add keep-alive timeout + receive-dispatch queue capacity; update validation/docs. |
| src/EasilyNET.Core/WebSocket/README.md | Update client documentation to protocol-level keep-alive and new dispatch semantics. |
| src/EasilyNET.Core/WebSocket/ManagedWebSocketClient.cs | Add persistent dispatch loop and remove heartbeat filtering/loop; improve send and state/close semantics. |
| sample/WebApi.Test.Unit/BackgroundServices/WebSocketClientTestService.cs | Update sample client to use protocol-level keep-alive; (currently forces test mode on). |
重构客户端测试服务,覆盖连接、状态机、回显、高并发、二进制、大消息、断开重连等多场景自动化断言,统一测试流程与统计输出。增强事件处理与日志,支持多轮连接/断开循环。服务端 ChatHandler 增加连接统计、消息计数、异常日志,优化日志输出与线程安全。整体提升测试覆盖率、可维护性和可观测性,为后续扩展打下基础。
将 TestMode 静态属性由返回 true 改为 false,切换为非测试模式运行。此更改可能影响测试逻辑分支,请关注相关用例行为变化。
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Joe Du <13188169+joesdu@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Joe Du <13188169+joesdu@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Joe Du <13188169+joesdu@users.noreply.github.com>
--- - 接收队列由 WebSocketMessageReceivedEventArgs 升级为携带 session 的 ReceivedEnvelope,提升消息归属判定能力 - 分发循环增加 session 校验,确保仅投递当前连接消息,避免断开/重连后旧消息误投递 - DrainReceiveChannel 方法同步适配,保证缓冲区安全释放 - 增强连接生命周期的消息隔离性与终态语义一致性
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 描述 (Description)
🔗 相关问题 (Related Issues)
🏷️ 变更类型 (Type of Change)
✅ 检查清单 (Checklist)
feature works)
🧪 测试 (Testing)
📸 截图 (如果适用) (Screenshots (if applicable))
🔍 附加说明 (Additional Notes)