Skip to content

Commit c2343f5

Browse files
authored
feat(FixLengthDataPackageHandler): support multiple sticky package (#6262)
* feat: 支持多次粘包处理功能 * test: 增加单元测试 * refactor: 代码重构提高可读性 * refactor: 精简代码提高可读性
1 parent 62ed6e6 commit c2343f5

File tree

2 files changed

+34
-27
lines changed

2 files changed

+34
-27
lines changed

src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,29 @@ public class FixLengthDataPackageHandler(int length) : DataPackageHandlerBase
2525
/// <returns></returns>
2626
public override async Task ReceiveAsync(Memory<byte> data)
2727
{
28-
// 处理上次粘包数据
29-
data = ConcatBuffer(data);
30-
31-
// 拷贝数据
32-
var len = length - _receivedLength;
33-
var segment = data.Length > len ? data[..len] : data;
34-
segment.CopyTo(_data[_receivedLength..]);
35-
36-
if (data.Length > len)
28+
while (data.Length > 0)
3729
{
38-
SlicePackage(data, data.Length - len);
39-
}
30+
// 拷贝数据
31+
var len = length - _receivedLength;
32+
var segment = data.Length > len ? data[..len] : data;
33+
segment.CopyTo(_data[_receivedLength..]);
4034

41-
// 更新已接收长度
42-
_receivedLength += segment.Length;
35+
// 更新数据
36+
data = data[segment.Length..];
4337

44-
// 如果已接收长度等于总长度则触发回调
45-
if (_receivedLength == length)
46-
{
47-
// 重置已接收长度
48-
_receivedLength = 0;
49-
if (ReceivedCallBack != null)
38+
// 更新已接收长度
39+
_receivedLength += segment.Length;
40+
41+
// 如果已接收长度等于总长度则触发回调
42+
if (_receivedLength == length)
5043
{
51-
await ReceivedCallBack(_data);
44+
// 重置已接收长度
45+
_receivedLength = 0;
46+
if (ReceivedCallBack != null)
47+
{
48+
await ReceivedCallBack(_data);
49+
}
50+
continue;
5251
}
5352
}
5453
}

test/UnitTest/Services/TcpSocketFactoryTest.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,22 @@ public async Task FixLengthDataPackageHandler_Sticky()
249249

250250
// 验证接收到的数据
251251
Assert.Equal(receivedBuffer.ToArray(), [1, 2, 3, 4, 5, 3, 4]);
252-
253-
// 等待第二次数据
254252
receivedBuffer = Memory<byte>.Empty;
255253
tcs = new TaskCompletionSource();
254+
255+
// 等待第二次数据
256256
await tcs.Task;
257257

258258
// 验证第二次收到的数据
259-
Assert.Equal(receivedBuffer.ToArray(), [1, 2, 3, 4, 5, 6, 7]);
259+
Assert.Equal(receivedBuffer.ToArray(), [2, 2, 3, 4, 5, 6, 7]);
260+
tcs = new TaskCompletionSource();
261+
await tcs.Task;
262+
263+
// 等待第二次数据
264+
await tcs.Task;
265+
266+
// 验证第三次收到的数据
267+
Assert.Equal(receivedBuffer.ToArray(), [3, 2, 3, 4, 5, 6, 7]);
260268

261269
// 关闭连接
262270
client.Close();
@@ -398,16 +406,16 @@ private static async Task MockStickyPackageAsync(TcpClient client)
398406
await stream.WriteAsync(block, CancellationToken.None);
399407

400408
// 模拟延时
401-
await Task.Delay(50);
409+
await Task.Delay(10);
402410

403411
// 模拟拆包发送第二段数据
404-
await stream.WriteAsync(new byte[] { 0x3, 0x4, 0x1, 0x2 }, CancellationToken.None);
412+
await stream.WriteAsync(new byte[] { 0x3, 0x4, 0x2, 0x2 }, CancellationToken.None);
405413

406414
// 模拟延时
407-
await Task.Delay(50);
415+
await Task.Delay(10);
408416

409417
// 模拟粘包发送后续数据
410-
await stream.WriteAsync(new byte[] { 0x3, 0x4, 0x5, 0x6, 0x7 }, CancellationToken.None);
418+
await stream.WriteAsync(new byte[] { 0x3, 0x4, 0x5, 0x6, 0x7, 0x3, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x1 }, CancellationToken.None);
411419
}
412420
}
413421

0 commit comments

Comments
 (0)