private async Task DoPersistentConnection(SocketDelegate socketDelegate, IHttpTransport transport, HttpContext context, DefaultConnectionContext connection) { try { await connection.Lock.WaitAsync(); if (connection.Status == DefaultConnectionContext.ConnectionStatus.Disposed) { _logger.ConnectionDisposed(connection.ConnectionId); // Connection was disposed context.Response.StatusCode = StatusCodes.Status404NotFound; return; } // There's already an active request if (connection.Status == DefaultConnectionContext.ConnectionStatus.Active) { _logger.ConnectionAlreadyActive(connection.ConnectionId, connection.GetHttpContext().TraceIdentifier); // Reject the request with a 409 conflict context.Response.StatusCode = StatusCodes.Status409Conflict; return; } // Mark the connection as active connection.Status = DefaultConnectionContext.ConnectionStatus.Active; // Call into the end point passing the connection connection.ApplicationTask = ExecuteApplication(socketDelegate, connection); // Start the transport connection.TransportTask = transport.ProcessRequestAsync(context, context.RequestAborted); } finally { connection.Lock.Release(); } // Wait for any of them to end await Task.WhenAny(connection.ApplicationTask, connection.TransportTask); await _manager.DisposeAndRemoveAsync(connection); }
private static async Task DoPersistentConnection(EndPoint endpoint, IHttpTransport transport, HttpContext context, Connection connection) { // Register this transport for disconnect RegisterDisconnect(context, connection); // Start the transport var transportTask = transport.ProcessRequestAsync(context); // Call into the end point passing the connection var endpointTask = endpoint.OnConnectedAsync(connection); // Wait for any of them to end await Task.WhenAny(endpointTask, transportTask); // Kill the channel connection.Channel.Dispose(); // Wait for both await Task.WhenAll(endpointTask, transportTask); }