Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8cf8794
chore: 更新解决方案增加扩展包
ArgoZhang Jun 20, 2025
c31b545
feat: 增加 ReceivedCallBack 回调方法
ArgoZhang Jun 20, 2025
7c39c48
test: 增加单元测试
ArgoZhang Jun 20, 2025
081236b
doc: 更新示例文档
ArgoZhang Jun 20, 2025
712e0dc
test: 增加 TouchSocket 单元测试
ArgoZhang Jun 20, 2025
d32f100
doc: 更新粘包分包文档
ArgoZhang Jun 20, 2025
4e78aba
feat: 增加 SendAsync 扩展方法
ArgoZhang Jun 20, 2025
52334b7
test: 增加单元测试
ArgoZhang Jun 20, 2025
a533852
Merge branch 'main' into feat-TouchSocket
ArgoZhang Jun 20, 2025
859b0cc
feat(tcp): 替换同步关闭方法为异步方法
RRQM Jun 20, 2025
82a93f4
refactor(tests): 使用异步方法关闭连接
RRQM Jun 20, 2025
517dc1f
doc: 更新数据处理器相关文档
ArgoZhang Jun 21, 2025
0f328a3
refactor: 增加 ConnectAsync 扩展方法
ArgoZhang Jun 21, 2025
336dd47
refactor: 更改关闭方法为同步方法
ArgoZhang Jun 21, 2025
93f68b6
test: 更新单元测试
ArgoZhang Jun 21, 2025
686e03b
Merge branch 'main' into feat-TouchSocket
ArgoZhang Jun 21, 2025
e23296f
doc: 增加数据适配器文档
ArgoZhang Jun 22, 2025
0f86b3c
doc: 增加新服务标记
ArgoZhang Jun 22, 2025
a2767ab
refactor: 更新 ITcpSocketFactory 接口定义
ArgoZhang Jun 22, 2025
60552bb
feat: 增加 GetOrCreate 扩展方法
ArgoZhang Jun 22, 2025
544fcd2
test: 更新单元测试
ArgoZhang Jun 22, 2025
d132af3
test: 增加单元测试
ArgoZhang Jun 22, 2025
66ab098
Merge branch 'main' into feat-TouchSocket
ArgoZhang Jun 23, 2025
0edee26
refactor: 更改 GetOrCreate 签名
ArgoZhang Jun 23, 2025
03bf822
test: 更新单元测试
ArgoZhang Jun 23, 2025
86a0333
refactor: 根据最新设计重构 TouchSocket 实现
ArgoZhang Jun 23, 2025
a97bc71
refactor: 整理项目文件
ArgoZhang Jun 23, 2025
7fc2eb1
Merge branch 'main' into feat-TouchSocket
ArgoZhang Jun 23, 2025
cc1a7ef
wip: 临时移除稍后再开分支合并到另外分支上
ArgoZhang Jun 23, 2025
1edbe34
chore: bump version 9.7.4-beta08
ArgoZhang Jun 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions BootstrapBlazor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{9BAF50BE
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTest.Benchmarks", "tools\Benchmarks\UnitTest.Benchmarks.csproj", "{3E6D8D0E-5A36-4CFD-8612-7D64E3FFE7B1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.TouchSocket", "..\BootstrapBlazor.Extensions\src\extensions\BootstrapBlazor.TouchSocket\BootstrapBlazor.TouchSocket.csproj", "{8B1D923C-5B6E-6068-BDAE-2752F7FF2D11}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -112,6 +114,10 @@ Global
{3E6D8D0E-5A36-4CFD-8612-7D64E3FFE7B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E6D8D0E-5A36-4CFD-8612-7D64E3FFE7B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E6D8D0E-5A36-4CFD-8612-7D64E3FFE7B1}.Release|Any CPU.Build.0 = Release|Any CPU
{8B1D923C-5B6E-6068-BDAE-2752F7FF2D11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B1D923C-5B6E-6068-BDAE-2752F7FF2D11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B1D923C-5B6E-6068-BDAE-2752F7FF2D11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B1D923C-5B6E-6068-BDAE-2752F7FF2D11}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -128,6 +134,7 @@ Global
{D8AEAFE7-10AF-4A5B-BC67-FE740A2CA1DF} = {7C1D79F1-87BC-42C1-BD5A-CDE4044AC1BD}
{C075C6C8-B9CB-4AC0-9BDF-B2002B4AB99C} = {EA765165-0542-41C8-93F2-85787FEDEDFF}
{3E6D8D0E-5A36-4CFD-8612-7D64E3FFE7B1} = {9BAF50BE-141D-4429-93A9-942F373D1F68}
{8B1D923C-5B6E-6068-BDAE-2752F7FF2D11} = {A2182155-43ED-44C1-BF6F-1B70EBD2DFFE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0DCB0756-34FA-4FD0-AE1D-D3F08B5B3A6B}
Expand Down
150 changes: 150 additions & 0 deletions test/UnitTest/Services/TouchSocketTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone

using Microsoft.Extensions.Logging;
using System.Net;
using System.Net.Sockets;

namespace UnitTest.Services;

public class TouchSocketTest
{
[Fact]
public async Task FixLengthDataPackageHandler_Ok()
{
var port = 8884;
var server = StartTcpServer(port, MockSplitPackageAsync);
var client = CreateClient();

// 测试 ConnectAsync 方法
var connect = await client.ConnectAsync("localhost", port);
Assert.True(connect);
Assert.True(client.IsConnected);

var tcs = new TaskCompletionSource();
ReadOnlyMemory<byte> receivedBuffer = ReadOnlyMemory<byte>.Empty;

// 增加数据处理适配器
client.SetDataHandler(new FixLengthDataPackageHandler(7)
{
ReceivedCallBack = buffer =>
{
receivedBuffer = buffer;
tcs.SetResult();
return ValueTask.CompletedTask;
}
});

// 测试 SendAsync 方法
var data = new ReadOnlyMemory<byte>([1, 2, 3, 4, 5]);
var result = await client.SendAsync(data);
Assert.True(result);

await tcs.Task;
Assert.Equal(receivedBuffer.ToArray(), [1, 2, 3, 4, 5, 3, 4]);

// 模拟延时等待内部继续读取逻辑完成,测试内部 _receiveCancellationTokenSource 取消逻辑
await Task.Delay(10);

// 关闭连接
client.Close();
StopTcpServer(server);
}

private static async Task MockSplitPackageAsync(TcpClient client)
{
using var stream = client.GetStream();
while (true)
{
var buffer = new byte[10240];
var len = await stream.ReadAsync(buffer);
if (len == 0)
{
break;
}

// 回写数据到客户端
var block = new ReadOnlyMemory<byte>(buffer, 0, len);
await stream.WriteAsync(block, CancellationToken.None);

// 模拟延时
await Task.Delay(50);

// 模拟拆包发送第二段数据
await stream.WriteAsync(new byte[] { 0x3, 0x4 }, CancellationToken.None);
}
}

private static TcpListener StartTcpServer(int port, Func<TcpClient, Task> handler)
{
var server = new TcpListener(IPAddress.Loopback, port);
server.Start();
Task.Run(() => AcceptClientsAsync(server, handler));
return server;
}

private static async Task AcceptClientsAsync(TcpListener server, Func<TcpClient, Task> handler)
{
while (true)
{
var client = await server.AcceptTcpClientAsync();
_ = Task.Run(() => handler(client));
}
}

private static void StopTcpServer(TcpListener server)
{
server?.Stop();
}

private static ITcpSocketClient CreateClient()
{
var sc = new ServiceCollection();
sc.AddLogging(builder =>
{
builder.AddProvider(new MockLoggerProvider());
});
sc.AddBootstrapBlazorTcpSocketFactory();

// 增加 TouchSocket 服务
sc.AddBootstrapBlazorTouchSocketService();

Check failure on line 112 in test/UnitTest/Services/TouchSocketTest.cs

View workflow job for this annotation

GitHub Actions / run test

'ServiceCollection' does not contain a definition for 'AddBootstrapBlazorTouchSocketService' and no accessible extension method 'AddBootstrapBlazorTouchSocketService' accepting a first argument of type 'ServiceCollection' could be found (are you missing a using directive or an assembly reference?)

var provider = sc.BuildServiceProvider();
var factory = provider.GetRequiredService<ITcpSocketFactory>();
var client = factory.GetOrCreate("localhost", 0);
return client;
}

class MockLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new MockLogger();
}

public void Dispose()
{

}
}

class MockLogger : ILogger
{
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
return null;
}

public bool IsEnabled(LogLevel logLevel)
{
return true;
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{

}
}
}
1 change: 1 addition & 0 deletions test/UnitTest/UnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\BootstrapBlazor.Extensions\src\extensions\BootstrapBlazor.TouchSocket\BootstrapBlazor.TouchSocket.csproj" />
<ProjectReference Include="..\..\src\BootstrapBlazor\BootstrapBlazor.csproj" />
</ItemGroup>

Expand Down
Loading