77using System . Net ;
88using System . Net . Sockets ;
99using System . Text ;
10+ using static System . Runtime . InteropServices . JavaScript . JSType ;
1011
1112namespace UnitTest . Services ;
1213
@@ -24,17 +25,17 @@ public async Task GetOrCreate_Ok()
2425 sc . AddBootstrapBlazorTcpSocketFactory ( ) ;
2526 var provider = sc . BuildServiceProvider ( ) ;
2627 var factory = provider . GetRequiredService < ITcpSocketFactory > ( ) ;
27- var client1 = factory . GetOrCreate ( "demo" , key => Utility . ConvertToIpEndPoint ( "localhost" , 0 ) ) ;
28+ var client1 = factory . GetOrCreate ( "demo" , op => op . LocalEndPoint = Utility . ConvertToIpEndPoint ( "localhost" , 0 ) ) ;
2829 await client1 . CloseAsync ( ) ;
2930
30- var client2 = factory . GetOrCreate ( "demo" , key => Utility . ConvertToIpEndPoint ( "localhost" , 0 ) ) ;
31+ var client2 = factory . GetOrCreate ( "demo" , op => op . LocalEndPoint = Utility . ConvertToIpEndPoint ( "localhost" , 0 ) ) ;
3132 Assert . Equal ( client1 , client2 ) ;
3233
3334 var ip = Dns . GetHostAddresses ( Dns . GetHostName ( ) , AddressFamily . InterNetwork ) . FirstOrDefault ( ) ?? IPAddress . Loopback ;
34- var client3 = factory . GetOrCreate ( "demo1" , key => Utility . ConvertToIpEndPoint ( ip . ToString ( ) , 0 ) ) ;
35+ var client3 = factory . GetOrCreate ( "demo1" , op => op . LocalEndPoint = Utility . ConvertToIpEndPoint ( ip . ToString ( ) , 0 ) ) ;
3536
3637 // 测试不合格 IP 地址
37- var client4 = factory . GetOrCreate ( "demo2" , key => Utility . ConvertToIpEndPoint ( "256.0.0.1" , 0 ) ) ;
38+ var client4 = factory . GetOrCreate ( "demo2" , op => op . LocalEndPoint = Utility . ConvertToIpEndPoint ( "256.0.0.1" , 0 ) ) ;
3839
3940 var client5 = factory . Remove ( "demo2" ) ;
4041 Assert . Equal ( client4 , client5 ) ;
@@ -102,6 +103,17 @@ public async Task SendAsync_Error()
102103 var data = new ReadOnlyMemory < byte > ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
103104 var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . SendAsync ( data ) ) ;
104105 Assert . NotNull ( ex ) ;
106+
107+ // 测试发送失败
108+ var port = 8892 ;
109+ var server = StartTcpServer ( port , MockSplitPackageAsync ) ;
110+
111+ client . SetDataHandler ( new MockSendErrorHandler ( ) ) ;
112+ await client . ConnectAsync ( "localhost" , port ) ;
113+ Assert . True ( client . IsConnected ) ;
114+
115+ // 内部生成异常日志
116+ await client . SendAsync ( data ) ;
105117 }
106118
107119 [ Fact ]
@@ -126,7 +138,7 @@ public async Task SendAsync_Cancel()
126138
127139 // 设置延时发送适配器
128140 // 延时发送期间关闭 Socket 连接导致内部报错
129- client . SetDataHandler ( new MockSendErrorHandler ( )
141+ client . SetDataHandler ( new MockSendCancelHandler ( )
130142 {
131143 Socket = client
132144 } ) ;
@@ -179,7 +191,10 @@ public async Task ReceiveAsync_Cancel()
179191 await client . SendAsync ( data ) ;
180192
181193 // 通过反射取消令牌
182- var fieldInfo = client . GetType ( ) . GetField ( "_receiveCancellationTokenSource" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
194+ var baseType = client . GetType ( ) . BaseType ;
195+ Assert . NotNull ( baseType ) ;
196+
197+ var fieldInfo = baseType . GetField ( "_receiveCancellationTokenSource" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
183198 Assert . NotNull ( fieldInfo ) ;
184199 var tokenSource = fieldInfo . GetValue ( client ) as CancellationTokenSource ;
185200 Assert . NotNull ( tokenSource ) ;
@@ -190,36 +205,21 @@ public async Task ReceiveAsync_Cancel()
190205 [ Fact ]
191206 public async Task ReceiveAsync_InvalidOperationException ( )
192207 {
193- var port = 8890 ;
194- var server = StartTcpServer ( port , MockSplitPackageAsync ) ;
195-
208+ // 未连接时调用 ReceiveAsync 方法会抛出 InvalidOperationException 异常
196209 var client = CreateClient ( ) ;
197-
198- //未连接
199210 var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . ReceiveAsync ( ) ) ;
200211 Assert . NotNull ( ex ) ;
201212
202- // 反射给 _client 赋值但是未连接
203- var fieldInfo = client . GetType ( ) . GetField ( "_client" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
204- Assert . NotNull ( fieldInfo ) ;
205- fieldInfo . SetValue ( client , new TcpClient ( ) ) ;
206- ex = null ;
207- ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . ReceiveAsync ( ) ) ;
208- Assert . NotNull ( ex ) ;
209-
210- await client . ConnectAsync ( "localhost" , port ) ;
211- ex = null ;
212- ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . ReceiveAsync ( ) ) ;
213+ // 已连接但是启用了自动接收功能时调用 ReceiveAsync 方法会抛出 InvalidOperationException 异常
214+ var port = 8893 ;
215+ var server = StartTcpServer ( port , MockSplitPackageAsync ) ;
213216
214- await client . CloseAsync ( ) ;
215- client . IsAutoReceive = false ;
217+ client . IsAutoReceive = true ;
216218 var connected = await client . ConnectAsync ( "localhost" , port ) ;
217219 Assert . True ( connected ) ;
218220
219- var data = new ReadOnlyMemory < byte > ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
220- await client . SendAsync ( data ) ;
221- var payload = await client . ReceiveAsync ( ) ;
222- Assert . Equal ( payload . ToArray ( ) , [ 1 , 2 , 3 , 4 , 5 ] ) ;
221+ ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . ReceiveAsync ( ) ) ;
222+ Assert . NotNull ( ex ) ;
223223 }
224224
225225 [ Fact ]
@@ -230,9 +230,13 @@ public async Task ReceiveAsync_Ok()
230230
231231 var client = CreateClient ( ) ;
232232 client . IsAutoReceive = false ;
233- await client . ConnectAsync ( "localhost" , port ) ;
233+ var connected = await client . ConnectAsync ( "localhost" , port ) ;
234+ Assert . True ( connected ) ;
235+
234236 var data = new ReadOnlyMemory < byte > ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
235- await client . SendAsync ( data ) ;
237+ var send = await client . SendAsync ( data ) ;
238+ Assert . True ( send ) ;
239+
236240 var payload = await client . ReceiveAsync ( ) ;
237241 Assert . Equal ( payload . ToArray ( ) , [ 1 , 2 , 3 , 4 , 5 ] ) ;
238242 }
@@ -243,7 +247,10 @@ public async Task ReceiveAsync_Error()
243247 var client = CreateClient ( ) ;
244248
245249 // 测试未建立连接前调用 ReceiveAsync 方法报异常逻辑
246- var methodInfo = client . GetType ( ) . GetMethod ( "AutoReceiveAsync" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
250+ var baseType = client . GetType ( ) . BaseType ;
251+ Assert . NotNull ( baseType ) ;
252+
253+ var methodInfo = baseType . GetMethod ( "AutoReceiveAsync" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
247254 Assert . NotNull ( methodInfo ) ;
248255
249256 var task = ( ValueTask ) methodInfo . Invoke ( client , null ) ! ;
@@ -567,7 +574,7 @@ private static ITcpSocketClient CreateClient()
567574 sc . AddBootstrapBlazorTcpSocketFactory ( ) ;
568575 var provider = sc . BuildServiceProvider ( ) ;
569576 var factory = provider . GetRequiredService < ITcpSocketFactory > ( ) ;
570- var client = factory . GetOrCreate ( "test" , key => Utility . ConvertToIpEndPoint ( "localhost" , 0 ) ) ;
577+ var client = factory . GetOrCreate ( "test" , op => op . LocalEndPoint = Utility . ConvertToIpEndPoint ( "localhost" , 0 ) ) ;
571578 return client ;
572579 }
573580
@@ -606,6 +613,16 @@ class MockSendErrorHandler : DataPackageHandlerBase
606613 {
607614 public ITcpSocketClient ? Socket { get ; set ; }
608615
616+ public override ValueTask < ReadOnlyMemory < byte > > SendAsync ( ReadOnlyMemory < byte > data , CancellationToken token = default )
617+ {
618+ throw new Exception ( "Mock send failed" ) ;
619+ }
620+ }
621+
622+ class MockSendCancelHandler : DataPackageHandlerBase
623+ {
624+ public ITcpSocketClient ? Socket { get ; set ; }
625+
609626 public override async ValueTask < ReadOnlyMemory < byte > > SendAsync ( ReadOnlyMemory < byte > data , CancellationToken token = default )
610627 {
611628 if ( Socket != null )
0 commit comments