30
30
//---------------------------------------------------------------------------
31
31
32
32
using System ;
33
- using System . Buffers ;
34
33
using System . IO ;
35
34
using System . IO . Pipelines ;
36
35
using System . Net ;
@@ -71,12 +70,10 @@ internal class SocketFrameHandler : IFrameHandler
71
70
private readonly ITcpClient _socket ;
72
71
private readonly ChannelWriter < OutgoingFrame > _channelWriter ;
73
72
private readonly ChannelReader < OutgoingFrame > _channelReader ;
74
- private readonly ChannelWriter < InboundFrame > _frameWriter ;
75
- public ChannelReader < InboundFrame > FrameReader { get ; }
76
- private readonly PipeReader _pipeReader ;
73
+ public PipeReader PipeReader { get ; private set ; }
74
+
77
75
private readonly PipeWriter _pipeWriter ;
78
76
private readonly Task _writerTask ;
79
- private readonly Task _readerTask ;
80
77
private readonly object _semaphore = new object ( ) ;
81
78
private readonly byte [ ] _frameHeaderBuffer ;
82
79
private readonly IMeasuredDuplexPipe _pipe ;
@@ -94,18 +91,8 @@ public SocketFrameHandler(AmqpTcpEndpoint endpoint, Func<AddressFamily, ITcpClie
94
91
SingleWriter = false
95
92
} ) ;
96
93
97
- var frameChannel = Channel . CreateUnbounded < InboundFrame > (
98
- new UnboundedChannelOptions
99
- {
100
- AllowSynchronousContinuations = true ,
101
- SingleReader = true ,
102
- SingleWriter = true
103
- } ) ;
104
-
105
94
_channelReader = channel . Reader ;
106
95
_channelWriter = channel . Writer ;
107
- _frameWriter = frameChannel . Writer ;
108
- FrameReader = frameChannel . Reader ;
109
96
110
97
// Resolve the hostname to know if it's even possible to even try IPv6
111
98
IPAddress [ ] adds = Dns . GetHostAddresses ( endpoint . HostName ) ;
@@ -162,12 +149,11 @@ public SocketFrameHandler(AmqpTcpEndpoint endpoint, Func<AddressFamily, ITcpClie
162
149
_pipe = SocketConnection . Create ( _socket . Client ) ;
163
150
}
164
151
165
- _pipeReader = _pipe . Input ;
152
+ PipeReader = _pipe . Input ;
166
153
_pipeWriter = _pipe . Output ;
167
154
168
155
WriteTimeout = writeTimeout ;
169
156
_writerTask = Task . Run ( WriteLoop , CancellationToken . None ) ;
170
- _readerTask = Task . Run ( ReadLoop , CancellationToken . None ) ;
171
157
}
172
158
public AmqpTcpEndpoint Endpoint { get ; set ; }
173
159
@@ -226,7 +212,6 @@ public void Close()
226
212
if ( ! _closed )
227
213
{
228
214
_channelWriter . TryComplete ( ) ;
229
- _frameWriter . TryComplete ( ) ;
230
215
try { _writerTask . GetAwaiter ( ) . GetResult ( ) ; } catch { }
231
216
232
217
if ( _pipe != null )
@@ -246,7 +231,7 @@ public void Close()
246
231
247
232
public void SendHeader ( )
248
233
{
249
- Span < byte > headerBytes = stackalloc byte [ 8 ] ;
234
+ Span < byte > headerBytes = _pipeWriter . GetSpan ( 8 ) ;
250
235
headerBytes [ 0 ] = ( byte ) 'A' ;
251
236
headerBytes [ 1 ] = ( byte ) 'M' ;
252
237
headerBytes [ 2 ] = ( byte ) 'Q' ;
@@ -266,64 +251,18 @@ public void SendHeader()
266
251
headerBytes [ 7 ] = ( byte ) Endpoint . Protocol . MinorVersion ;
267
252
}
268
253
269
- Memory < byte > pipeMemory = _pipeWriter . GetMemory ( 8 ) ;
270
- headerBytes . CopyTo ( pipeMemory . Span ) ;
271
- _pipeWriter . Advance ( headerBytes . Length ) ;
272
- _pipeWriter . FlushAsync ( ) . AsTask ( ) . GetAwaiter ( ) . GetResult ( ) ;
273
- }
274
-
275
- public void Write ( OutgoingFrame frame )
276
- {
277
- _channelWriter . TryWrite ( frame ) ;
278
- }
279
-
280
- private async Task ReadLoop ( )
281
- {
282
- bool allowSync = true ;
283
- try
254
+ _pipeWriter . Advance ( 8 ) ;
255
+ if ( ! _pipeWriter . FlushAsync ( ) . AsTask ( ) . Wait ( _writeableStateTimeout ) )
284
256
{
285
- while ( true )
286
- {
287
- // Let's read some bytes
288
- if ( ! ( allowSync && _pipeReader . TryRead ( out ReadResult readResult ) ) )
289
- {
290
- readResult = await _pipeReader . ReadAsync ( ) . ConfigureAwait ( false ) ;
291
- }
292
-
293
- int handled = 0 ;
294
- ReadOnlySequence < byte > buffer = readResult . Buffer ;
295
- if ( ! buffer . IsEmpty )
296
- {
297
- handled = ProcessBuffer ( ref buffer ) ;
298
- }
299
-
300
- allowSync = handled != 0 ;
301
- _pipeReader . AdvanceTo ( buffer . Start , buffer . End ) ;
302
-
303
- if ( handled == 0 && readResult . IsCompleted )
304
- {
305
- break ;
306
- }
307
- }
257
+ var timeout = new TimeoutException ( ) ;
258
+ _pipeWriter . Complete ( timeout ) ;
259
+ _channelWriter . Complete ( timeout ) ;
308
260
}
309
- catch ( Exception e )
310
- {
311
- _frameWriter . TryComplete ( e ) ;
312
- }
313
-
314
- _frameWriter . TryComplete ( new EndOfStreamException ( ) ) ;
315
261
}
316
262
317
- private int ProcessBuffer ( ref ReadOnlySequence < byte > buffer )
263
+ public void Write ( OutgoingFrame frame )
318
264
{
319
- int handled = 0 ;
320
- while ( InboundFrame . TryReadFrame ( ref buffer , out InboundFrame frame ) )
321
- {
322
- _frameWriter . TryWrite ( frame ) ;
323
- handled ++ ;
324
- }
325
-
326
- return handled ;
265
+ _channelWriter . TryWrite ( frame ) ;
327
266
}
328
267
329
268
private async Task WriteLoop ( )
0 commit comments