1111using System . Net . Security ;
1212using System . Net . Sockets ;
1313using System . Runtime . CompilerServices ;
14- using System . Threading . Channels ;
1514
1615namespace Sisk . Cadente ;
1716
@@ -20,19 +19,19 @@ namespace Sisk.Cadente;
2019/// </summary>
2120public sealed class HttpHost : IDisposable {
2221
23- const int MAX_WORKERS = 65536 ;
24-
2522 private readonly TcpListener _listener ;
26- private readonly Channel < TcpClient > clientQueue ;
27- private readonly ChannelWriter < TcpClient > writerQueue ;
28- private readonly ChannelReader < TcpClient > readerQueue ;
29- private readonly Thread channelConsumerThread ;
3023
3124 // internal readonly SemaphoreSlim HostLimiter = new SemaphoreSlim ( 64 );
3225 private readonly LingerOption tcpLingerOption = new LingerOption ( true , 0 ) ;
3326
3427 private bool disposedValue ;
3528
29+ /// <summary>
30+ /// Gets or sets the client queue size of all <see cref="HttpHost"/> instances. This value indicates how many
31+ /// connections the server can maintain simultaneously before queueing other connections attempts.
32+ /// </summary>
33+ public static int QueueSize { get ; set ; } = 1024 ;
34+
3635 /// <summary>
3736 /// Gets or sets the action handler for HTTP requests.
3837 /// </summary>
@@ -60,12 +59,6 @@ public sealed class HttpHost : IDisposable {
6059 /// <param name="endpoint">The <see cref="IPEndPoint"/> to listen on.</param>
6160 public HttpHost ( IPEndPoint endpoint ) {
6261 this . _listener = new TcpListener ( endpoint ) ;
63- this . channelConsumerThread = new Thread ( this . ConsumerJobThread ) ;
64- this . clientQueue = Channel . CreateBounded < TcpClient > (
65- new BoundedChannelOptions ( MAX_WORKERS ) { SingleReader = true , SingleWriter = true , AllowSynchronousContinuations = true } ) ;
66-
67- this . readerQueue = this . clientQueue . Reader ;
68- this . writerQueue = this . clientQueue . Writer ;
6962 }
7063
7164 /// <summary>
@@ -86,27 +79,25 @@ public void Start () {
8679 this . _listener . Server . SetSocketOption ( SocketOptionLevel . Tcp , SocketOptionName . TcpKeepAliveRetryCount , 3 ) ;
8780 this . _listener . Server . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . KeepAlive , true ) ;
8881
89- this . _listener . Start ( ) ;
82+ this . _listener . Start ( QueueSize ) ;
9083 this . _listener . BeginAcceptTcpClient ( this . ReceiveClient , null ) ;
91-
92- this . channelConsumerThread . Start ( ) ;
9384 }
9485
9586 private async void ReceiveClient ( IAsyncResult result ) {
9687
9788 this . _listener . BeginAcceptTcpClient ( this . ReceiveClient , null ) ;
9889 var client = this . _listener . EndAcceptTcpClient ( result ) ;
9990
100- await this . writerQueue . WriteAsync ( client ) ;
91+ await this . HandleTcpClient ( client ) ;
10192 }
10293
10394 private async Task HandleTcpClient ( TcpClient client ) {
10495 try {
10596 { // setup the tcpclient
10697 client . NoDelay = true ;
10798
108- // client.ReceiveTimeout = this.TimeoutManager._ClientReadTimeoutSeconds;
109- // client.SendTimeout = this.TimeoutManager._ClientWriteTimeoutSeconds;
99+ client . ReceiveTimeout = this . TimeoutManager . _ClientReadTimeoutSeconds ;
100+ client . SendTimeout = this . TimeoutManager . _ClientWriteTimeoutSeconds ;
110101
111102 client . ReceiveBufferSize = HttpConnection . REQUEST_BUFFER_SIZE ;
112103 client . SendBufferSize = HttpConnection . RESPONSE_BUFFER_SIZE ;
@@ -148,19 +139,10 @@ await sslStream.AuthenticateAsServerAsync (
148139 }
149140 }
150141
151- async void ConsumerJobThread ( ) {
152- while ( ! this . disposedValue && await this . readerQueue . WaitToReadAsync ( ) ) {
153- while ( ! this . disposedValue && this . readerQueue . TryRead ( out var client ) ) {
154- _ = this . HandleTcpClient ( client ) ;
155- }
156- }
157- }
158-
159142 private void Dispose ( bool disposing ) {
160143 if ( ! this . disposedValue ) {
161144 if ( disposing ) {
162145 this . _listener . Dispose ( ) ;
163- this . channelConsumerThread . Join ( ) ;
164146 }
165147
166148 this . disposedValue = true ;
0 commit comments