diff --git a/.editorconfig b/.editorconfig index cfb50819..61033d26 100644 --- a/.editorconfig +++ b/.editorconfig @@ -216,7 +216,7 @@ csharp_preserve_single_line_blocks = true visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion [*.cs] # Add file header -file_header_template = Copyright (c) Argo Zhang (argo@163.com). All rights reserved.\nLicensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\nWebsite: https://www.blazor.zone or https://argozhang.github.io/ +file_header_template = Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.\nLicensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\nWebsite: https://www.blazor.zone or https://argozhang.github.io/ csharp_style_namespace_declarations = file_scoped:suggestion csharp_style_expression_bodied_local_functions = true:silent csharp_using_directive_placement = outside_namespace:silent diff --git a/BootstrapBlazor.Extensions.sln b/BootstrapBlazor.Extensions.sln index 7dbcbca8..c5d4f29b 100644 --- a/BootstrapBlazor.Extensions.sln +++ b/BootstrapBlazor.Extensions.sln @@ -647,6 +647,7 @@ Global {01007B10-7C3C-4136-83FF-981CA39AD3D4} = {7B29E81D-92DE-46C8-8EDC-1B48C8F12BC2} {835C8BA9-A9CC-4EA0-9002-34A20F8B2E86} = {B6A98ADE-D26A-4D0B-8978-AB7AC915F5AE} {30C57119-C564-401C-AE3A-6203E2733E1A} = {FF1089BE-C704-4374-B629-C57C08E1798F} + {98054DCC-A9AB-CB11-798F-424112EC8639} = {7B29E81D-92DE-46C8-8EDC-1B48C8F12BC2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D5EB1960-6F30-4CE1-B375-EAE1F787D6FF} diff --git a/src/extensions/BootstrapBlazor.Socket/BootstrapBlazor.Socket.csproj b/src/extensions/BootstrapBlazor.Socket/BootstrapBlazor.Socket.csproj index 940fb5fe..cf6fc6cf 100644 --- a/src/extensions/BootstrapBlazor.Socket/BootstrapBlazor.Socket.csproj +++ b/src/extensions/BootstrapBlazor.Socket/BootstrapBlazor.Socket.csproj @@ -1,7 +1,7 @@  - 9.0.0 + 9.0.1 diff --git a/src/extensions/BootstrapBlazor.Socket/DataAdapter/DataPackageAdapter.cs b/src/extensions/BootstrapBlazor.Socket/DataAdapter/DataPackageAdapter.cs index 315994c2..de35e3cb 100644 --- a/src/extensions/BootstrapBlazor.Socket/DataAdapter/DataPackageAdapter.cs +++ b/src/extensions/BootstrapBlazor.Socket/DataAdapter/DataPackageAdapter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ @@ -7,22 +7,18 @@ namespace BootstrapBlazor.DataAdapters; /// /// Provides a base implementation for adapting data packages between different systems or formats. /// +/// 实例 /// This abstract class serves as a foundation for implementing custom data package adapters. It defines /// common methods for sending, receiving, and handling data packages, as well as a property for accessing the /// associated data package handler. Derived classes should override the virtual methods to provide specific behavior /// for handling data packages. -public class DataPackageAdapter : IDataPackageAdapter +public class DataPackageAdapter(IDataPackageHandler? DataPackageHandler = null) : IDataPackageAdapter { /// /// /// public Func, ValueTask>? ReceivedCallBack { get; set; } - /// - /// - /// - public IDataPackageHandler? DataPackageHandler { get; set; } - /// /// /// @@ -33,10 +29,7 @@ public virtual async ValueTask HandlerAsync(ReadOnlyMemory data, Cancellat { if (DataPackageHandler != null) { - if (DataPackageHandler.ReceivedCallBack == null) - { - DataPackageHandler.ReceivedCallBack = OnHandlerReceivedCallBack; - } + DataPackageHandler.ReceivedCallBack ??= OnHandlerReceivedCallBack; // 如果存在数据处理器则调用其处理方法 await DataPackageHandler.HandlerAsync(data, token); diff --git a/src/extensions/BootstrapBlazor.Socket/DataAdapter/IDataPackageAdapter.cs b/src/extensions/BootstrapBlazor.Socket/DataAdapter/IDataPackageAdapter.cs index 5e5a0268..1dc43b1a 100644 --- a/src/extensions/BootstrapBlazor.Socket/DataAdapter/IDataPackageAdapter.cs +++ b/src/extensions/BootstrapBlazor.Socket/DataAdapter/IDataPackageAdapter.cs @@ -20,11 +20,6 @@ public interface IDataPackageAdapter /// issues. Func, ValueTask>? ReceivedCallBack { get; set; } - /// - /// Gets the handler responsible for processing data packages. - /// - IDataPackageHandler? DataPackageHandler { get; } - /// /// Asynchronously receives data from a source and processes it. /// diff --git a/src/extensions/BootstrapBlazor.TcpSocket/BootstrapBlazor.TcpSocket.csproj b/src/extensions/BootstrapBlazor.TcpSocket/BootstrapBlazor.TcpSocket.csproj index 33f5d97a..e2f2ddc7 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/BootstrapBlazor.TcpSocket.csproj +++ b/src/extensions/BootstrapBlazor.TcpSocket/BootstrapBlazor.TcpSocket.csproj @@ -1,11 +1,11 @@  - 9.0.0 + 9.0.1 - BootstrapBlazor Socket + BootstrapBlazor Socket TcpClient BootstrapBlazor extensions of TcpSocket diff --git a/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClient.cs b/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClient.cs index 30e0830c..72f7c237 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClient.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClient.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClientProvider.cs b/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClientProvider.cs index 5d31cf4d..8fa3e886 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClientProvider.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketClientProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketFactory.cs b/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketFactory.cs index 627a579b..7fb40486 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketFactory.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/DefaultTcpSocketFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/src/extensions/BootstrapBlazor.TcpSocket/Extensions/ITcpSocketClientExtensions.cs b/src/extensions/BootstrapBlazor.TcpSocket/Extensions/ITcpSocketClientExtensions.cs index f02ecb34..1de3aed6 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/Extensions/ITcpSocketClientExtensions.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/Extensions/ITcpSocketClientExtensions.cs @@ -1,7 +1,6 @@ -// 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(argo@live.ca) Website: https://www.blazor.zone +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -52,6 +51,55 @@ public static ValueTask ConnectAsync(this ITcpSocketClient client, string return client.ConnectAsync(endPoint, token); } + private static readonly Dictionary, ValueTask> Callback)>> _cache = []; + + /// + /// 增加 数据适配器及其对应的回调方法 + /// + /// + /// + /// + public static void AddDataPackageAdapter(this ITcpSocketClient client, IDataPackageAdapter adapter, Func, ValueTask> callback) + { + if (_cache.TryGetValue(client, out var list)) + { + list.Add((adapter, cb)); + } + else + { + _cache.Add(client, [(adapter, cb)]); + } + + client.ReceivedCallBack += cb; + + // 设置 DataPackageAdapter 的回调函数 + adapter.ReceivedCallBack = callback; + + async ValueTask cb(ReadOnlyMemory buffer) + { + // 将接收到的数据传递给 DataPackageAdapter 进行数据处理合规数据触发 ReceivedCallBack 回调 + await adapter.HandlerAsync(buffer); + } + } + + /// + /// 移除 数据适配器及其对应的回调方法 + /// + /// + /// + public static void RemoveDataPackageAdapter(this ITcpSocketClient client, Func, ValueTask> callback) + { + if (_cache.TryGetValue(client, out var list)) + { + var items = list.Where(i => i.Adapter.ReceivedCallBack == callback).ToList(); + foreach (var c in items) + { + client.ReceivedCallBack -= c.Callback; + list.Remove(c); + } + } + } + /// /// Configures the specified to use the provided /// for processing received data and sets a callback to handle processed data. @@ -67,6 +115,16 @@ public static ValueTask ConnectAsync(this ITcpSocketClient client, string /// containing the processed data and returns a . public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageAdapter adapter, Func, ValueTask> callback) { + // 释放缓存 + if (_cache.TryGetValue(client, out var list)) + { + foreach (var (Adapter, Callback) in list) + { + client.ReceivedCallBack -= Callback; + } + list.Clear(); + } + // 设置 ITcpSocketClient 的回调函数 client.ReceivedCallBack = async buffer => { @@ -75,7 +133,18 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPack }; // 设置 DataPackageAdapter 的回调函数 - adapter.ReceivedCallBack = buffer => callback(buffer); + adapter.ReceivedCallBack = callback; + } + + /// + /// 通过指定 数据处理实例,设置数据适配器并配置回调方法 + /// + /// 实例 + /// 数据处理实例 + /// 回调方法 + public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageHandler handler, Func, ValueTask> callback) + { + client.SetDataPackageAdapter(new DataPackageAdapter(handler), callback); } /// @@ -92,6 +161,16 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPack /// The callback function to be invoked with the converted entity. public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageAdapter adapter, IDataConverter socketDataConverter, Func callback) { + // 释放缓存 + if (_cache.TryGetValue(client, out var list)) + { + foreach (var (Adapter, Callback) in list) + { + client.ReceivedCallBack -= Callback; + } + list.Clear(); + } + // 设置 ITcpSocketClient 的回调函数 client.ReceivedCallBack = async buffer => { @@ -111,6 +190,19 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, }; } + /// + /// 通过指定 数据处理实例,设置数据适配器并配置回调方法 + /// + /// + /// + /// + /// + /// + public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageHandler handler, IDataConverter socketDataConverter, Func callback) + { + client.SetDataPackageAdapter(new DataPackageAdapter(handler), socketDataConverter, callback); + } + /// /// Configures the specified to use a custom data package adapter and callback /// function. @@ -126,6 +218,16 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, /// The callback function to invoke with the processed entity of type . public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageAdapter adapter, Func callback) { + // 释放缓存 + if (_cache.TryGetValue(client, out var list)) + { + foreach (var (Adapter, Callback) in list) + { + client.ReceivedCallBack -= Callback; + } + list.Clear(); + } + // 设置 ITcpSocketClient 的回调函数 client.ReceivedCallBack = async buffer => { @@ -163,6 +265,17 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, } } + /// + /// 通过指定 数据处理实例,设置数据适配器并配置回调方法 + /// + /// 实例 + /// 数据处理实例 + /// 回调方法 + public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageHandler handler, Func callback) + { + client.SetDataPackageAdapter(new DataPackageAdapter(handler), callback); + } + private static void SetDataAdapterCallback(this IDataPackageAdapter adapter, IDataConverter converter, Func callback) { adapter.ReceivedCallBack = async buffer => diff --git a/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketExtensions.cs b/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketExtensions.cs index 3371ccb4..e3d2cbf9 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketExtensions.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketUtility.cs b/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketUtility.cs index 1118828a..3c563331 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketUtility.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/Extensions/TcpSocketUtility.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ @@ -48,7 +48,6 @@ public static IPAddress ConvertToIPAddress(string ipString) } [ExcludeFromCodeCoverage] - [UnsupportedOSPlatform("browser")] private static IPAddress IPAddressByHostName => Dns.GetHostAddresses(Dns.GetHostName(), AddressFamily.InterNetwork).FirstOrDefault() ?? IPAddress.Any; diff --git a/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClient.cs b/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClient.cs index dcf58028..3e491134 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClient.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClient.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClientProvider.cs b/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClientProvider.cs index 14647fa6..00b82018 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClientProvider.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketClientProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketFactory.cs b/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketFactory.cs index b791809c..c97065a3 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketFactory.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/ITcpSocketFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/src/extensions/BootstrapBlazor.TcpSocket/TcpSocketClientOptions.cs b/src/extensions/BootstrapBlazor.TcpSocket/TcpSocketClientOptions.cs index 40a43441..88907b1e 100644 --- a/src/extensions/BootstrapBlazor.TcpSocket/TcpSocketClientOptions.cs +++ b/src/extensions/BootstrapBlazor.TcpSocket/TcpSocketClientOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ diff --git a/test/UnitTestTcpSocket/TcpSocketFactoryTest.cs b/test/UnitTestTcpSocket/TcpSocketFactoryTest.cs index 76673d60..a7a1e4d9 100644 --- a/test/UnitTestTcpSocket/TcpSocketFactoryTest.cs +++ b/test/UnitTestTcpSocket/TcpSocketFactoryTest.cs @@ -496,10 +496,7 @@ public async Task FixLengthDataPackageHandler_Ok() var receivedBuffer = new byte[1024]; // 设置数据适配器 - var adapter = new DataPackageAdapter - { - DataPackageHandler = new FixLengthDataPackageHandler(7) - }; + var adapter = new DataPackageAdapter(new FixLengthDataPackageHandler(7)); client.SetDataPackageAdapter(adapter, buffer => { // buffer 即是接收到的数据 @@ -540,11 +537,7 @@ public async Task FixLengthDataPackageHandler_Sticky() var connect = await client.ConnectAsync("localhost", port); // 设置数据适配器 - var adapter = new DataPackageAdapter - { - DataPackageHandler = new FixLengthDataPackageHandler(7) - }; - + var adapter = new DataPackageAdapter(new FixLengthDataPackageHandler(7)); client.SetDataPackageAdapter(adapter, buffer => { // buffer 即是接收到的数据 @@ -594,10 +587,7 @@ public async Task DelimiterDataPackageHandler_Ok() var receivedBuffer = new byte[128]; // 设置数据适配器 - var adapter = new DataPackageAdapter - { - DataPackageHandler = new DelimiterDataPackageHandler([13, 10]), - }; + var adapter = new DataPackageAdapter(new DelimiterDataPackageHandler([13, 10])); client.SetDataPackageAdapter(adapter, buffer => { // buffer 即是接收到的数据 @@ -650,10 +640,7 @@ public async Task TryConvertTo_Ok() MockEntity? entity = null; // 设置数据适配器 - var adapter = new DataPackageAdapter - { - DataPackageHandler = new FixLengthDataPackageHandler(29), - }; + var adapter = new DataPackageAdapter(new FixLengthDataPackageHandler(29)); client.SetDataPackageAdapter(adapter, new DataConverter(), t => { entity = t; @@ -789,10 +776,7 @@ public async Task TryGetTypeConverter_Ok() var connect = await client.ConnectAsync("localhost", port); // 设置数据适配器 - var adapter = new DataPackageAdapter - { - DataPackageHandler = new FixLengthDataPackageHandler(7) - }; + var adapter = new DataPackageAdapter(new FixLengthDataPackageHandler(7)); OptionConvertEntity? entity = null; client.SetDataPackageAdapter(adapter, data => @@ -816,6 +800,122 @@ public async Task TryGetTypeConverter_Ok() server.Stop(); } + [Fact] + public async Task AddDataPackageAdapter_Ok() + { + var port = 8896; + var server = StartTcpServer(port, MockSplitPackageAsync); + + var client = CreateClient(); + var tcs = new TaskCompletionSource(); + var receivedBuffer = new byte[128]; + var receivedBuffer2 = new byte[128]; + + // 连接 TCP Server + var connect = await client.ConnectAsync("localhost", port); + + client.AddDataPackageAdapter(new DataPackageAdapter(new FixLengthDataPackageHandler(7)), ReceivedCallBack); + client.AddDataPackageAdapter(new DataPackageAdapter(new FixLengthDataPackageHandler(7)), ReceivedCallBack2); + + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); + await client.SendAsync(data); + + // 等待接收数据处理完成 + await tcs.Task; + client.RemoveDataPackageAdapter(ReceivedCallBack); + client.RemoveDataPackageAdapter(ReceivedCallBack2); + + ValueTask ReceivedCallBack(ReadOnlyMemory buffer) + { + // buffer 即是接收到的数据 + buffer.CopyTo(receivedBuffer); + receivedBuffer = receivedBuffer[..buffer.Length]; + tcs.SetResult(); + return ValueTask.CompletedTask; + } + + ValueTask ReceivedCallBack2(ReadOnlyMemory buffer) + { + // buffer 即是接收到的数据 + buffer.CopyTo(receivedBuffer2); + receivedBuffer2 = receivedBuffer2[..buffer.Length]; + return ValueTask.CompletedTask; + } + } + + [Fact] + public async Task SetDataPackageAdapter_Ok() + { + var port = 8897; + var server = StartTcpServer(port, MockSplitPackageAsync); + + var client = CreateClient(); + var tcs = new TaskCompletionSource(); + var receivedBuffer = new byte[128]; + + // 连接 TCP Server + var connect = await client.ConnectAsync("localhost", port); + + client.AddDataPackageAdapter(new DataPackageAdapter(new FixLengthDataPackageHandler(7)), ReceivedCallBack); + client.SetDataPackageAdapter(new FixLengthDataPackageHandler(7), ReceivedCallBack); + + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); + await client.SendAsync(data); + + // 等待接收数据处理完成 + await tcs.Task; + + ValueTask ReceivedCallBack(ReadOnlyMemory buffer) + { + // buffer 即是接收到的数据 + buffer.CopyTo(receivedBuffer); + receivedBuffer = receivedBuffer[..buffer.Length]; + tcs.SetResult(); + return ValueTask.CompletedTask; + } + } + + [Fact] + public async Task SetDataPackageAdapter_Generic() + { + var port = 8898; + var server = StartTcpServer(port, MockSplitPackageAsync); + + var client = CreateClient(); + var tcs = new TaskCompletionSource(); + var receivedBuffer = new byte[128]; + + // 连接 TCP Server + var connect = await client.ConnectAsync("localhost", port); + + client.AddDataPackageAdapter(new DataPackageAdapter(new FixLengthDataPackageHandler(7)), ReceivedCallBack); + client.SetDataPackageAdapter(new FixLengthDataPackageHandler(7), ReceivedEntityCallBack); + + client.AddDataPackageAdapter(new DataPackageAdapter(new FixLengthDataPackageHandler(7)), ReceivedCallBack); + client.SetDataPackageAdapter(new FixLengthDataPackageHandler(7), new MockSocketDataConverter(), ReceivedEntityCallBack); + + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); + await client.SendAsync(data); + + // 等待接收数据处理完成 + await tcs.Task; + + ValueTask ReceivedCallBack(ReadOnlyMemory buffer) + { + // buffer 即是接收到的数据 + buffer.CopyTo(receivedBuffer); + receivedBuffer = receivedBuffer[..buffer.Length]; + tcs.SetResult(); + return ValueTask.CompletedTask; + } + + Task ReceivedEntityCallBack(MockEntity? entity) + { + tcs.SetResult(); + return Task.CompletedTask; + } + } + private static TcpListener StartTcpServer(int port, Func handler) { var server = new TcpListener(IPAddress.Loopback, port);