From fabf9e4f290c3cae8d4fdb6ea1f9ba7c19748b8e Mon Sep 17 00:00:00 2001 From: root <295172551@qq.com> Date: Sat, 26 Jul 2025 21:26:02 +0800 Subject: [PATCH] fix(websocket): optimize message validation logic, remove redundant MaxMessageSize check in handler adapter --- .../WebSocketMessageHandlerAdapter.cs | 16 +++- src/modify.md | 96 ++++++++++++++++++- 2 files changed, 107 insertions(+), 5 deletions(-) diff --git a/src/X1.WebSocket/Handlers/WebSocketMessageHandlerAdapter.cs b/src/X1.WebSocket/Handlers/WebSocketMessageHandlerAdapter.cs index fedeeea..134cc30 100644 --- a/src/X1.WebSocket/Handlers/WebSocketMessageHandlerAdapter.cs +++ b/src/X1.WebSocket/Handlers/WebSocketMessageHandlerAdapter.cs @@ -114,13 +114,21 @@ namespace CellularManagement.WebSocket.Handlers return false; } - if (message.Data.Length > _options.MaxMessageSize) + // 检查消息大小是否超过缓冲区容量 + // 这是技术层面的检查,防止缓冲区溢出 + var actualBufferSize = _options.GetActualBufferSize(); + if (message.Data.Length > actualBufferSize) { - _logger.LogWarning("消息大小超过限制,处理器:{HandlerName},连接ID:{ConnectionId},大小:{Size},限制:{MaxSize}", - Name, message.ConnectionId, message.Data.Length, _options.MaxMessageSize); - return false; + _logger.LogError("消息大小超过缓冲区容量,处理器:{HandlerName},连接ID:{ConnectionId},大小:{Size}字节,缓冲区容量:{BufferSize}字节", + Name, message.ConnectionId, message.Data.Length, actualBufferSize); + return false; // 超过缓冲区容量时拒绝处理 } + // 注意:不检查 MaxMessageSize,因为: + // 1. message.Data 已经是完整接收的消息数据 + // 2. 在接收阶段已经通过缓冲区容量检查 + // 3. 业务限制检查在接收阶段已经完成并记录警告 + return true; } diff --git a/src/modify.md b/src/modify.md index 9252247..1133319 100644 --- a/src/modify.md +++ b/src/modify.md @@ -592,4 +592,98 @@ builder.Services.AddWebSocketServices(options => - **分离了技术限制和业务限制** - **提供了足够的缓冲区空间处理客户端数据** - **保持了数据完整性** -- **提高了系统的健壮性和可维护性** \ No newline at end of file +- **提高了系统的健壮性和可维护性** + +## 2024-12-19 WebSocketMessageHandlerAdapter 验证逻辑修复 + +### 修改文件 +- `X1.WebSocket/Handlers/WebSocketMessageHandlerAdapter.cs` + +### 问题描述 +在 `ValidateMessage` 方法中存在验证逻辑不一致的问题: +```csharp +// 问题代码 +if (message.Data.Length > _options.MaxMessageSize) +{ + _logger.LogWarning("消息大小超过限制..."); + return false; // 拒绝处理消息 +} +``` + +**问题所在:** +1. **与缓冲区大小修复不一致**:我们刚刚修复了缓冲区大小问题,允许处理超过业务限制的消息 +2. **数据完整性冲突**:拒绝处理大消息会导致数据丢失 +3. **业务逻辑混乱**:业务限制应该是警告而非拒绝处理的理由 + +### 根本原因分析 + +#### 1. 设计理念不一致 +- **缓冲区修复**:允许接收大消息,记录警告但继续处理 +- **验证逻辑**:拒绝处理大消息,导致数据丢失 +- **结果**:修复了接收问题,但处理时仍然拒绝 + +#### 2. 业务限制的定位错误 +- **业务限制**:应该是性能监控和资源管理的参考 +- **当前实现**:被当作拒绝处理的硬性条件 +- **影响**:无法处理客户端发送的大数据 + +### 修复方案 + +#### 1. 修改验证逻辑 +```csharp +// 检查消息大小是否超过缓冲区容量 +// 这是技术层面的检查,防止缓冲区溢出 +var actualBufferSize = _options.GetActualBufferSize(); +if (message.Data.Length > actualBufferSize) +{ + _logger.LogError("消息大小超过缓冲区容量,处理器:{HandlerName},连接ID:{ConnectionId},大小:{Size}字节,缓冲区容量:{BufferSize}字节", + Name, message.ConnectionId, message.Data.Length, actualBufferSize); + return false; // 超过缓冲区容量时拒绝处理 +} + +// 注意:不检查 MaxMessageSize,因为: +// 1. message.Data 已经是完整接收的消息数据 +// 2. 在接收阶段已经通过缓冲区容量检查 +// 3. 业务限制检查在接收阶段已经完成并记录警告 +``` + +#### 2. 保持数据完整性 +- **移除拒绝逻辑**:不再因为大小超限而拒绝处理 +- **保留警告记录**:继续记录业务层面的警告信息 +- **确保处理**:保证所有消息都能被正确处理 + +### 技术细节 + +#### 1. 验证策略调整 +- **必需验证**:消息为空、连接ID为空、数据为空 +- **技术验证**:消息大小超过缓冲区容量(拒绝处理) +- **处理策略**:技术验证失败时拒绝,其他情况继续处理 + +#### 2. 日志级别优化 +- **Error 级别**:用于缓冲区容量超限等严重错误 +- **Warning 级别**:用于其他验证失败的警告 +- **Debug 级别**:用于正常处理的调试信息 + +#### 3. 业务逻辑一致性 +- **接收层**:负责缓冲区容量检查和业务限制检查 +- **处理层**:只负责缓冲区容量检查,业务限制已在接收层处理 +- **整体策略**:职责分离,避免重复验证 + +### 性能影响 +- **处理效率**:避免重复验证,提高处理性能 +- **职责清晰**:接收层和处理层职责分离 +- **稳定性**:保持必要的技术验证,确保系统稳定 +- **一致性**:与缓冲区大小修复保持一致 + +### 测试建议 +1. 测试不同大小消息的处理 +2. 验证缓冲区容量检查的正确性 +3. 确认消息处理的完整性 +4. 检查日志记录的准确性 + +### 总结 +这次修复确保了 WebSocket 消息处理的职责分离: +- **接收层负责完整验证**:缓冲区容量 + 业务限制 +- **处理层负责必要验证**:只检查缓冲区容量 +- **避免重复验证**:提高性能和代码清晰度 +- **保持数据完整性**:确保系统稳定性和一致性 \ No newline at end of file