diff --git a/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor b/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor
index 267c5c135c9..a17c58fe686 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor
@@ -22,6 +22,7 @@ private ITcpSocketFactory? TcpSocketFactory { get; set; }
通过 ITcpSocketClient 实例方法 SendAsync 发送协议数据
通过 ITcpSocketClient 实例方法 Close 关闭连接
通过 ITcpSocketClient 实例方法 SetDataHandler 方法设置数据处理器
+ 通过 ITcpSocketClient 实例属性 ReceivedCallBack 方法设置接收数据处理器(注意:此回调未做任何数据处理为原始数据)
4. 数据处理器
@@ -31,13 +32,13 @@ private ITcpSocketFactory? TcpSocketFactory { get; set; }
数据处理器设计初衷就是为了契合通讯协议大大简化我们开发逻辑,我们已通讯协议每次通讯电文均为 4 位定长举例说明,在实际的通讯过程中,我们接收到的通讯数据存在粘包或者分包的现象
- - 粘包:比如我们期望收到 1234 四个字符,实际上我们接收到的是 123412 多出来的 12 其实是下一个通讯电文的内容,相邻两个通讯数据包的粘连称为粘包
- - 分包:比如我们期望收到 1234 四个字符,实际上我们接收到的是 12 和 34 两个数据包,这种情况称为分包
+ - 粘包:比如我们期望收到 1234 四个字符,实际上我们接收到的是 123412 多出来的 12 其实是下一个通讯电文的内容,相邻两个通讯数据包的粘连称为粘包
+ - 分包:比如我们期望收到 1234 四个字符,实际上我们接收到的是 12 和 34 两个数据包,这种情况称为分包
-我们内置了 IDataPackageHandler 数据包处理接口,已经虚类 DataPackageHandlerBase 作为数据处理器基类已经内置了 粘包 分包 的逻辑,继承此类后专注自己处理的业务即可
+我们内置了一些常用的数据处理类 IDataPackageHandler 接口为数据包处理接口,虚类 DataPackageHandlerBase 作为数据处理器基类已经内置了 粘包 分包 的逻辑,继承此类后专注自己处理的业务即可
-此外我们还内置了 FixLengthDataPackageHandler 固定长度数据处理器 使用方法如下:
+使用方法如下:
[Inject]
[NotNull]
@@ -64,3 +65,10 @@ private async Task CreateClient()
var connected = await client.ConnectAsync("192.168.10.100", 6688);
}
+
+内置数据库处理器
+
+
+ FixLengthDataPackageHandler 固定长度数据处理器 即每个通讯包都是固定长度
+ DelimiterDataPackageHandler 分隔符数据处理器 即通讯包以特定一个或一组字节分割
+
diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs
index e3040ba0e3d..3cb6c4500e5 100644
--- a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs
+++ b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs
@@ -16,8 +16,11 @@ public abstract class DataPackageHandlerBase : IDataPackageHandler
private Memory _lastReceiveBuffer = Memory.Empty;
///
- /// 当接收数据处理完成后,回调该函数执行接收
+ /// Gets or sets the callback function to handle received data.
///
+ /// The callback function should be designed to handle the received data efficiently and
+ /// asynchronously. Ensure that the implementation does not block or perform long-running operations, as this may
+ /// impact performance.
public Func, ValueTask>? ReceivedCallBack { get; set; }
///
diff --git a/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs b/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs
index 84b3f462393..33679cb473b 100644
--- a/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs
+++ b/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs
@@ -28,6 +28,8 @@ class DefaultTcpSocketClient : ITcpSocketClient
public int ReceiveBufferSize { get; set; } = 1024 * 10;
+ public Func, ValueTask>? ReceivedCallBack { get; set; }
+
public DefaultTcpSocketClient(string host, int port = 0)
{
LocalEndPoint = new IPEndPoint(GetIPAddress(host), port);
@@ -136,6 +138,11 @@ private async ValueTask ReceiveAsync()
{
buffer = buffer[..len];
+ if (ReceivedCallBack != null)
+ {
+ await ReceivedCallBack(buffer);
+ }
+
if (_dataPackageHandler != null)
{
await _dataPackageHandler.ReceiveAsync(buffer);
diff --git a/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs b/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs
index 211203c2be5..339ad56c42a 100644
--- a/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs
+++ b/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs
@@ -30,6 +30,14 @@ public interface ITcpSocketClient : IDisposable
/// specific local endpoint, this property may return .
IPEndPoint LocalEndPoint { get; }
+ ///
+ /// Gets or sets the callback function to handle received data.
+ ///
+ /// The callback function should be designed to handle the received data efficiently and
+ /// asynchronously. Ensure that the implementation does not block or perform long-running operations, as this may
+ /// impact performance.
+ Func, ValueTask>? ReceivedCallBack { get; set; }
+
///
/// Configures the data handler to process incoming data packages.
///
diff --git a/test/UnitTest/Services/TcpSocketFactoryTest.cs b/test/UnitTest/Services/TcpSocketFactoryTest.cs
index c3bdf59bb67..9991ee021d8 100644
--- a/test/UnitTest/Services/TcpSocketFactoryTest.cs
+++ b/test/UnitTest/Services/TcpSocketFactoryTest.cs
@@ -143,12 +143,27 @@ public async Task ReceiveAsync_Error()
Assert.Equal(1024 * 20, client.ReceiveBufferSize);
client.SetDataHandler(new MockReceiveErrorHandler());
+
+ ReadOnlyMemory buffer = ReadOnlyMemory.Empty;
+ var tcs = new TaskCompletionSource();
+
+ // 增加接收回调方法
+ client.ReceivedCallBack = b =>
+ {
+ buffer = b;
+ tcs.SetResult();
+ return ValueTask.CompletedTask;
+ };
+
await client.ConnectAsync("localhost", port);
// 发送数据导致接收数据异常
var data = new ReadOnlyMemory([1, 2, 3, 4, 5]);
await client.SendAsync(data);
+ await tcs.Task;
+ Assert.Equal(buffer.ToArray(), [1, 2, 3, 4, 5]);
+
// 关闭连接
StopTcpServer(server);
}