33// Website: https://www.blazor.zone or https://argozhang.github.io/
44
55using System . Buffers ;
6+ using System . Diagnostics ;
67using System . IO . Pipelines ;
78using System . Net ;
89using TouchSocket . Core ;
910using TouchSocket . Sockets ;
1011
1112namespace BootstrapBlazor . Components ;
1213
13- sealed class DefaultTcpSocketProvider : TcpClientBase , ISocketClientProvider
14+ internal sealed class DefaultTcpSocketProvider : TcpClientBase , ISocketClientProvider
1415{
15- private readonly Pipe _pipe = new ( ) ;
16-
1716 /// <summary>
1817 /// <inheritdoc/>
1918 /// </summary>
20- public bool IsConnected => Online ;
19+ public bool IsConnected => base . Online ;
2120
2221 /// <summary>
2322 /// <inheritdoc/>
2423 /// </summary>
2524 public IPEndPoint LocalEndPoint { get ; set ; } = new IPEndPoint ( IPAddress . Any , 0 ) ;
2625
26+ /// <summary>
27+ /// <inheritdoc/>
28+ /// </summary>
29+ public async ValueTask CloseAsync ( )
30+ {
31+ await base . CloseAsync ( string . Empty ) ;
32+ }
33+
2734 /// <summary>
2835 /// <inheritdoc/>
2936 /// </summary>
@@ -32,53 +39,85 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
3239 await SetupAsync ( new TouchSocketConfig ( )
3340 . SetBindIPHost ( new IPHost ( LocalEndPoint . Address , LocalEndPoint . Port ) )
3441 . SetRemoteIPHost ( new IPHost ( endPoint . Address , endPoint . Port ) ) ) ;
35- await TcpConnectAsync ( int . MaxValue , token ) ;
36- if ( Online )
42+
43+ try
3744 {
45+ await TcpConnectAsync ( int . MaxValue , token ) ;
46+ Debug . Assert ( MainSocket != null , "MainSocket cannot be null after connection." ) ;
47+ Debug . Assert ( base . Online , "Online should be true after successful connection." ) ;
3848 if ( MainSocket . LocalEndPoint is IPEndPoint localEndPoint )
3949 {
4050 LocalEndPoint = localEndPoint ;
4151 }
52+ return true ;
53+ }
54+ catch ( Exception ex )
55+ {
56+ this . Logger ? . Exception ( this , ex ) ;
57+ return false ;
4258 }
43- return Online ;
44- }
45-
46- /// <summary>
47- /// <inheritdoc/>
48- /// </summary>
49- public async ValueTask < bool > SendAsync ( ReadOnlyMemory < byte > data , CancellationToken token = default )
50- {
51- await ProtectedDefaultSendAsync ( data , token ) ;
52- return true ;
5359 }
5460
5561 /// <summary>
5662 /// <inheritdoc/>
5763 /// </summary>
5864 public async ValueTask < int > ReceiveAsync ( Memory < byte > buffer , CancellationToken token = default )
5965 {
60- var result = await _pipe . Reader . ReadAsync ( token ) ;
66+ token . ThrowIfCancellationRequested ( ) ;
67+ this . ThrowIfTcpClientNotConnected ( ) ;
68+ this . ThrowIfDisposed ( ) ;
69+
70+ var result = await base . Transport . Input . ReadAsync ( token ) ;
6171 if ( result . IsCompleted )
6272 {
6373 return 0 ;
6474 }
75+ var length = ( int ) Math . Min ( result . Buffer . Length , buffer . Length ) ;
6576
66- result . Buffer . CopyTo ( buffer . Span ) ;
67- return ( int ) result . Buffer . Length ;
68- }
77+ var sequence = result . Buffer . Slice ( 0 , length ) ;
6978
70- protected override async ValueTask < bool > OnTcpReceiving ( ByteBlock byteBlock )
71- {
72- await _pipe . Writer . WriteAsync ( byteBlock . Memory ) ;
73- await _pipe . Writer . FlushAsync ( ) ;
74- return true ;
79+ sequence . CopyTo ( buffer . Span ) ;
80+ base . Transport . Input . AdvanceTo ( sequence . End ) ;
81+ return length ;
7582 }
7683
7784 /// <summary>
7885 /// <inheritdoc/>
7986 /// </summary>
80- public async ValueTask CloseAsync ( )
87+ public async ValueTask < bool > SendAsync ( ReadOnlyMemory < byte > data , CancellationToken token = default )
88+ {
89+ token . ThrowIfCancellationRequested ( ) ;
90+ base . ThrowIfTcpClientNotConnected ( ) ;
91+ base . ThrowIfDisposed ( ) ;
92+ var pipeWriter = base . Transport . Output ;
93+ var locker = base . Transport . SemaphoreSlimForWriter ;
94+ await locker . WaitAsync ( token ) ;
95+ try
96+ {
97+ pipeWriter . Write ( data . Span ) ;
98+ var result = await pipeWriter . FlushAsync ( token ) ;
99+ if ( result . IsCanceled || result . IsCompleted )
100+ {
101+ return false ;
102+ }
103+ return true ;
104+ }
105+ catch ( Exception ex )
106+ {
107+ this . Logger ? . Exception ( this , ex ) ;
108+ return false ;
109+ }
110+ finally
111+ {
112+ locker . Release ( ) ;
113+ }
114+ }
115+
116+ protected override sealed async Task ReceiveLoopAsync ( ITransport transport )
81117 {
82- await CloseAsync ( string . Empty ) ;
118+ //重写接收循环方法
119+ //此处不做任何数据读取
120+ //让数据直接到ReceiveAsync使用管道直接读取数据
121+ await Task . Delay ( - 1 , transport . ClosedToken ) ;
83122 }
84123}
0 commit comments