Skip to content

Commit 40bbd3b

Browse files
committed
chore: 更新文档
1 parent 02bedde commit 40bbd3b

3 files changed

Lines changed: 194 additions & 0 deletions

File tree

Cyaim.WebSocketServer/Cluster/Cyaim.WebSocketServer.Cluster.Hybrid/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,24 @@ await clusterTransport.StartAsync();
765765
app.Run();
766766
```
767767

768+
## Message Deduplication / 消息去重机制
769+
770+
### Automatic Duplicate Prevention / 自动防止重复处理
771+
772+
`HybridClusterTransport` has built-in message deduplication to ensure messages are not processed multiple times:
773+
774+
`HybridClusterTransport` 内置了消息去重机制,确保消息不会被重复处理:
775+
776+
1. **Target Node Check** - Only the target node processes messages intended for it / **目标节点检查** - 只有目标节点会处理指定目标的消息
777+
2. **Message ID Deduplication** - Uses message ID to prevent processing the same message twice / **消息ID去重** - 使用消息ID防止重复处理同一消息
778+
3. **Automatic Cleanup** - Periodically cleans up expired message ID records / **自动清理** - 定期清理过期的消息ID记录
779+
780+
### How It Works / 工作原理
781+
782+
- **Target Node Check / 目标节点检查**: If `ToNodeId` is set and not equal to current node, message is ignored / 如果 `ToNodeId` 已设置且不等于当前节点,消息会被忽略
783+
- **Message ID Deduplication / 消息ID去重**: Each message has unique `MessageId`, duplicate messages are automatically ignored / 每个消息都有唯一的 `MessageId`,重复消息会被自动忽略
784+
- **Automatic Cleanup / 自动清理**: Message ID cache is cleaned every 5 minutes (retains last 10 minutes) / 消息ID缓存每5分钟清理一次(保留最近10分钟)
785+
768786
## Troubleshooting / 故障排除
769787

770788
### Nodes Not Discovering Each Other / 节点无法相互发现
@@ -786,6 +804,14 @@ app.Run();
786804
- Verify node status is `Active` / 验证节点状态为 `Active`
787805
- If using custom `nodeInfoProvider`, ensure it returns valid data / 如果使用自定义 `nodeInfoProvider`,确保它返回有效数据
788806

807+
### Messages Being Processed Multiple Times / 消息被重复处理
808+
809+
-**Fixed / 已修复**: `HybridClusterTransport` has built-in message deduplication / `HybridClusterTransport` 内置消息去重机制
810+
- If still experiencing duplicates, check / 如果仍然出现重复,请检查:
811+
- Message `MessageId` is unique / 消息的 `MessageId` 是否唯一
812+
- Message `ToNodeId` is correctly set / 消息的 `ToNodeId` 是否正确设置
813+
- Logs for deduplication messages / 日志中的去重消息提示
814+
789815
## License / 许可证
790816

791817
See LICENSE file for details.

Cyaim.WebSocketServer/docs/en/HYBRID_CLUSTER.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,82 @@ timer.Start();
932932
app.Run();
933933
```
934934

935+
## Message Deduplication Mechanism
936+
937+
### Automatic Duplicate Prevention
938+
939+
`HybridClusterTransport` has built-in message deduplication to ensure messages are not processed multiple times:
940+
941+
1. **Target Node Check** - Only the target node processes messages intended for it
942+
2. **Message ID Deduplication** - Uses message ID to prevent processing the same message twice
943+
3. **Automatic Cleanup** - Periodically cleans up expired message ID records (every 5 minutes, keeps records from last 10 minutes)
944+
945+
### How It Works
946+
947+
```text
948+
Message Arrives → Check if from self → Check target node → Check if processed → Process message
949+
```
950+
951+
#### Target Node Check
952+
953+
- If message's `ToNodeId` is not empty and not equal to current node ID, message is ignored
954+
- If `ToNodeId` is `null` (broadcast message), all nodes process it (but deduplicated by message ID)
955+
- If `ToNodeId` equals current node ID, message is processed
956+
957+
#### Message ID Deduplication
958+
959+
- Each message has a unique `MessageId`
960+
- Before processing, checks if this `MessageId` has been processed
961+
- If already processed, message is ignored to prevent duplicate processing
962+
963+
### Example Scenarios
964+
965+
**Scenario 1: Unicast Message (Specific Target Node)**
966+
967+
```csharp
968+
// Node 1 sends message to Node 2
969+
await clusterTransport.SendAsync("node2", new ClusterMessage { ... });
970+
971+
// Result:
972+
// - Node 2: Processes message ✅
973+
// - Node 1, Node 3: Ignore message (because ToNodeId != own node ID) ✅
974+
```
975+
976+
**Scenario 2: Broadcast Message**
977+
978+
```csharp
979+
// Node 1 broadcasts message
980+
await clusterTransport.BroadcastAsync(new ClusterMessage { ... });
981+
982+
// Result:
983+
// - All nodes: Receive message
984+
// - But deduplicated by message ID, ensuring each node processes only once ✅
985+
```
986+
987+
**Scenario 3: Duplicate Message Arrival (Network Retransmission, etc.)**
988+
989+
```csharp
990+
// If same message arrives multiple times due to network issues
991+
// Result:
992+
// - First time: Processed normally ✅
993+
// - Subsequent duplicates: Automatically ignored via message ID check ✅
994+
```
995+
996+
### Configuration
997+
998+
The message deduplication mechanism is **automatically enabled**, no configuration needed. The system will:
999+
1000+
- Automatically check target node
1001+
- Automatically use message ID for deduplication
1002+
- Automatically clean up expired message ID records (every 5 minutes)
1003+
1004+
### Performance Considerations
1005+
1006+
- Message ID cache uses in-memory storage, periodically cleaned to prevent memory leaks
1007+
- Cleanup interval: Every 5 minutes
1008+
- Retention time: Message IDs from last 10 minutes
1009+
- For high-concurrency scenarios, memory usage is minimal (each message ID uses about tens of bytes)
1010+
9351011
## Troubleshooting
9361012

9371013
### Nodes Not Discovering Each Other
@@ -952,6 +1028,14 @@ app.Run();
9521028
- Check connection count values
9531029
- Verify node status is `Active`
9541030

1031+
### Messages Being Processed Multiple Times
1032+
1033+
-**Fixed**: `HybridClusterTransport` has built-in message deduplication
1034+
- If still experiencing duplicate processing, check:
1035+
- Whether message's `MessageId` is unique
1036+
- Whether message's `ToNodeId` is correctly set
1037+
- Logs for "Ignoring duplicate message" or "Ignoring message - target node is" messages
1038+
9551039
## Related Documentation
9561040

9571041
- [Cluster Module Documentation](./CLUSTER.md)

Cyaim.WebSocketServer/docs/zh-cn/HYBRID_CLUSTER.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,82 @@ timer.Start();
932932
app.Run();
933933
```
934934

935+
## 消息去重机制
936+
937+
### 自动防止重复处理
938+
939+
`HybridClusterTransport` 内置了消息去重机制,确保消息不会被重复处理:
940+
941+
1. **目标节点检查** - 只有目标节点会处理指定目标的消息
942+
2. **消息ID去重** - 使用消息ID防止重复处理同一消息
943+
3. **自动清理** - 定期清理过期的消息ID记录(每5分钟清理一次,保留10分钟内的记录)
944+
945+
### 工作原理
946+
947+
```text
948+
消息到达 → 检查是否来自自己 → 检查目标节点 → 检查是否已处理 → 处理消息
949+
```
950+
951+
#### 目标节点检查
952+
953+
- 如果消息的 `ToNodeId` 不为空且不等于当前节点ID,消息会被忽略
954+
- 如果 `ToNodeId``null`(广播消息),所有节点都会处理(但会通过消息ID去重)
955+
- 如果 `ToNodeId` 等于当前节点ID,消息会被处理
956+
957+
#### 消息ID去重
958+
959+
- 每个消息都有唯一的 `MessageId`
960+
- 处理前会检查该 `MessageId` 是否已处理过
961+
- 如果已处理,消息会被忽略,避免重复处理
962+
963+
### 示例场景
964+
965+
**场景1:单播消息(指定目标节点)**
966+
967+
```csharp
968+
// 节点1发送消息给节点2
969+
await clusterTransport.SendAsync("node2", new ClusterMessage { ... });
970+
971+
// 结果:
972+
// - 节点2:处理消息 ✅
973+
// - 节点1、节点3:忽略消息(因为 ToNodeId != 自己的节点ID)✅
974+
```
975+
976+
**场景2:广播消息**
977+
978+
```csharp
979+
// 节点1广播消息
980+
await clusterTransport.BroadcastAsync(new ClusterMessage { ... });
981+
982+
// 结果:
983+
// - 所有节点:都会收到消息
984+
// - 但通过消息ID去重,确保每个节点只处理一次 ✅
985+
```
986+
987+
**场景3:消息重复到达(网络重传等)**
988+
989+
```csharp
990+
// 如果同一消息因为网络问题重复到达
991+
// 结果:
992+
// - 第一次:正常处理 ✅
993+
// - 后续重复:通过消息ID检测,自动忽略 ✅
994+
```
995+
996+
### 配置说明
997+
998+
消息去重机制是**自动启用**的,无需任何配置。系统会:
999+
1000+
- 自动检查目标节点
1001+
- 自动使用消息ID去重
1002+
- 自动清理过期的消息ID记录(每5分钟清理一次)
1003+
1004+
### 性能考虑
1005+
1006+
- 消息ID缓存使用内存存储,定期清理避免内存泄漏
1007+
- 清理间隔:每5分钟
1008+
- 保留时间:10分钟内的消息ID
1009+
- 对于高并发场景,内存占用很小(每个消息ID约占用几十字节)
1010+
9351011
## 故障排除
9361012

9371013
### 节点无法相互发现
@@ -952,6 +1028,14 @@ app.Run();
9521028
- 检查连接数值
9531029
- 验证节点状态为 `Active`
9541030

1031+
### 消息被重复处理
1032+
1033+
-**已修复**`HybridClusterTransport` 内置消息去重机制
1034+
- 如果仍然出现重复处理,请检查:
1035+
- 消息的 `MessageId` 是否唯一
1036+
- 消息的 `ToNodeId` 是否正确设置
1037+
- 日志中是否有 "Ignoring duplicate message" 或 "Ignoring message - target node is" 的提示
1038+
9551039
## 相关文档
9561040

9571041
- [集群模块文档](./CLUSTER.md)

0 commit comments

Comments
 (0)