1- // Licensed to the .NET Foundation under one or more agreements.
2- // The .NET Foundation licenses this file to you under the Apache 2.0 License
3- // See the LICENSE file in the project root for more information.
4- // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
1+ // Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
2+ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+ // Website: https://www.blazor.zone or https://argozhang.github.io/
54
65using Microsoft . Extensions . DependencyInjection ;
76using Microsoft . Extensions . Options ;
@@ -52,6 +51,55 @@ public static ValueTask<bool> ConnectAsync(this ITcpSocketClient client, string
5251 return client . ConnectAsync ( endPoint , token ) ;
5352 }
5453
54+ private static readonly Dictionary < ITcpSocketClient , List < ( IDataPackageAdapter Adapter , Func < ReadOnlyMemory < byte > , ValueTask > Callback ) > > _cache = [ ] ;
55+
56+ /// <summary>
57+ /// 增加 <see cref="ITcpSocketClient"/> 数据适配器及其对应的回调方法
58+ /// </summary>
59+ /// <param name="client"></param>
60+ /// <param name="adapter"></param>
61+ /// <param name="callback"></param>
62+ public static void AddDataPackageAdapter ( this ITcpSocketClient client , IDataPackageAdapter adapter , Func < ReadOnlyMemory < byte > , ValueTask > callback )
63+ {
64+ if ( _cache . TryGetValue ( client , out var list ) )
65+ {
66+ list . Add ( ( adapter , cb ) ) ;
67+ }
68+ else
69+ {
70+ _cache . Add ( client , [ ( adapter , cb ) ] ) ;
71+ }
72+
73+ client . ReceivedCallBack += cb ;
74+
75+ // 设置 DataPackageAdapter 的回调函数
76+ adapter . ReceivedCallBack = callback ;
77+
78+ async ValueTask cb ( ReadOnlyMemory < byte > buffer )
79+ {
80+ // 将接收到的数据传递给 DataPackageAdapter 进行数据处理合规数据触发 ReceivedCallBack 回调
81+ await adapter . HandlerAsync ( buffer ) ;
82+ }
83+ }
84+
85+ /// <summary>
86+ /// 移除 <see cref="ITcpSocketClient"/> 数据适配器及其对应的回调方法
87+ /// </summary>
88+ /// <param name="client"></param>
89+ /// <param name="callback"></param>
90+ public static void RemoveDataPackageAdapter ( this ITcpSocketClient client , Func < ReadOnlyMemory < byte > , ValueTask > callback )
91+ {
92+ if ( _cache . TryGetValue ( client , out var list ) )
93+ {
94+ var items = list . Where ( i => i . Adapter . ReceivedCallBack == callback ) . ToList ( ) ;
95+ foreach ( var c in items )
96+ {
97+ client . ReceivedCallBack -= c . Callback ;
98+ list . Remove ( c ) ;
99+ }
100+ }
101+ }
102+
55103 /// <summary>
56104 /// Configures the specified <see cref="ITcpSocketClient"/> to use the provided <see cref="IDataPackageAdapter"/>
57105 /// for processing received data and sets a callback to handle processed data.
@@ -67,6 +115,16 @@ public static ValueTask<bool> ConnectAsync(this ITcpSocketClient client, string
67115 /// containing the processed data and returns a <see cref="ValueTask"/>.</param>
68116 public static void SetDataPackageAdapter ( this ITcpSocketClient client , IDataPackageAdapter adapter , Func < ReadOnlyMemory < byte > , ValueTask > callback )
69117 {
118+ // 释放缓存
119+ if ( _cache . TryGetValue ( client , out var list ) )
120+ {
121+ foreach ( var ( Adapter , Callback ) in list )
122+ {
123+ client . ReceivedCallBack -= Callback ;
124+ }
125+ list . Clear ( ) ;
126+ }
127+
70128 // 设置 ITcpSocketClient 的回调函数
71129 client . ReceivedCallBack = async buffer =>
72130 {
@@ -75,7 +133,18 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPack
75133 } ;
76134
77135 // 设置 DataPackageAdapter 的回调函数
78- adapter . ReceivedCallBack = buffer => callback ( buffer ) ;
136+ adapter . ReceivedCallBack = callback ;
137+ }
138+
139+ /// <summary>
140+ /// 通过指定 <see cref="IDataPackageHandler"/> 数据处理实例,设置数据适配器并配置回调方法
141+ /// </summary>
142+ /// <param name="client"><see cref="ITcpSocketClient"/> 实例</param>
143+ /// <param name="handler"><see cref="IDataPackageHandler"/> 数据处理实例</param>
144+ /// <param name="callback">回调方法</param>
145+ public static void SetDataPackageAdapter ( this ITcpSocketClient client , IDataPackageHandler handler , Func < ReadOnlyMemory < byte > , ValueTask > callback )
146+ {
147+ client . SetDataPackageAdapter ( new DataPackageAdapter ( handler ) , callback ) ;
79148 }
80149
81150 /// <summary>
@@ -92,6 +161,16 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPack
92161 /// <param name="callback">The callback function to be invoked with the converted entity.</param>
93162 public static void SetDataPackageAdapter < TEntity > ( this ITcpSocketClient client , IDataPackageAdapter adapter , IDataConverter < TEntity > socketDataConverter , Func < TEntity ? , Task > callback )
94163 {
164+ // 释放缓存
165+ if ( _cache . TryGetValue ( client , out var list ) )
166+ {
167+ foreach ( var ( Adapter , Callback ) in list )
168+ {
169+ client . ReceivedCallBack -= Callback ;
170+ }
171+ list . Clear ( ) ;
172+ }
173+
95174 // 设置 ITcpSocketClient 的回调函数
96175 client . ReceivedCallBack = async buffer =>
97176 {
@@ -111,6 +190,19 @@ public static void SetDataPackageAdapter<TEntity>(this ITcpSocketClient client,
111190 } ;
112191 }
113192
193+ /// <summary>
194+ /// 通过指定 <see cref="IDataPackageHandler"/> 数据处理实例,设置数据适配器并配置回调方法
195+ /// </summary>
196+ /// <typeparam name="TEntity"></typeparam>
197+ /// <param name="client"></param>
198+ /// <param name="handler"></param>
199+ /// <param name="socketDataConverter"></param>
200+ /// <param name="callback"></param>
201+ public static void SetDataPackageAdapter < TEntity > ( this ITcpSocketClient client , IDataPackageHandler handler , IDataConverter < TEntity > socketDataConverter , Func < TEntity ? , Task > callback )
202+ {
203+ client . SetDataPackageAdapter ( new DataPackageAdapter ( handler ) , socketDataConverter , callback ) ;
204+ }
205+
114206 /// <summary>
115207 /// Configures the specified <see cref="ITcpSocketClient"/> to use a custom data package adapter and callback
116208 /// function.
@@ -126,6 +218,16 @@ public static void SetDataPackageAdapter<TEntity>(this ITcpSocketClient client,
126218 /// <param name="callback">The callback function to invoke with the processed entity of type <typeparamref name="TEntity"/>.</param>
127219 public static void SetDataPackageAdapter < TEntity > ( this ITcpSocketClient client , IDataPackageAdapter adapter , Func < TEntity ? , Task > callback )
128220 {
221+ // 释放缓存
222+ if ( _cache . TryGetValue ( client , out var list ) )
223+ {
224+ foreach ( var ( Adapter , Callback ) in list )
225+ {
226+ client . ReceivedCallBack -= Callback ;
227+ }
228+ list . Clear ( ) ;
229+ }
230+
129231 // 设置 ITcpSocketClient 的回调函数
130232 client . ReceivedCallBack = async buffer =>
131233 {
@@ -163,6 +265,17 @@ public static void SetDataPackageAdapter<TEntity>(this ITcpSocketClient client,
163265 }
164266 }
165267
268+ /// <summary>
269+ /// 通过指定 <see cref="IDataPackageHandler"/> 数据处理实例,设置数据适配器并配置回调方法
270+ /// </summary>
271+ /// <param name="client"><see cref="ITcpSocketClient"/> 实例</param>
272+ /// <param name="handler"><see cref="IDataPackageHandler"/> 数据处理实例</param>
273+ /// <param name="callback">回调方法</param>
274+ public static void SetDataPackageAdapter < TEntity > ( this ITcpSocketClient client , IDataPackageHandler handler , Func < TEntity ? , Task > callback )
275+ {
276+ client . SetDataPackageAdapter ( new DataPackageAdapter ( handler ) , callback ) ;
277+ }
278+
166279 private static void SetDataAdapterCallback < TEntity > ( this IDataPackageAdapter adapter , IDataConverter < TEntity > converter , Func < TEntity ? , Task > callback )
167280 {
168281 adapter . ReceivedCallBack = async buffer =>
0 commit comments