private async Task Execute(TTransport client, CancellationToken cancellationToken) { Logger.LogTrace("Started client request processing"); var processor = ProcessorFactory.GetAsyncProcessor(client, this); TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; object connectionContext = null; try { try { inputTransport = InputTransportFactory.GetTransport(client); outputTransport = OutputTransportFactory.GetTransport(client); inputProtocol = InputProtocolFactory.GetProtocol(inputTransport); outputProtocol = OutputProtocolFactory.GetProtocol(outputTransport); if (ServerEventHandler != null) { connectionContext = await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken); } while (!cancellationToken.IsCancellationRequested) { if (!await inputTransport.PeekAsync(cancellationToken)) { break; } if (ServerEventHandler != null) { await ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken); } if (!await processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken)) { break; } } } catch (TTransportException ttx) { Logger.LogTrace($"Transport exception: {ttx}"); } catch (Exception x) { Logger.LogError($"Error: {x}"); } if (ServerEventHandler != null) { await ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken); } } finally { //Close transports inputTransport?.Close(); outputTransport?.Close(); // disposable stuff should be disposed inputProtocol?.Dispose(); outputProtocol?.Dispose(); inputTransport?.Dispose(); outputTransport?.Dispose(); } Logger.LogTrace("Completed client request processing"); }
/// <summary> /// Loops on processing a client forever /// client will be a TTransport instance /// </summary> /// <param name="client"></param> private async Task ExecuteAsync(TTransport client) { var cancellationToken = ServerCancellationToken; var processor = ProcessorFactory.GetAsyncProcessor(client, this); TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; object connectionContext = null; try { try { inputTransport = InputTransportFactory.GetTransport(client); outputTransport = OutputTransportFactory.GetTransport(client); inputProtocol = InputProtocolFactory.GetProtocol(inputTransport); outputProtocol = OutputProtocolFactory.GetProtocol(outputTransport); //Recover event handler (if any) and fire createContext server event when a client connects if (ServerEventHandler != null) { connectionContext = await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken); } //Process client requests until client disconnects while (!(stop || cancellationToken.IsCancellationRequested)) { if (!await inputTransport.PeekAsync(cancellationToken)) { break; } //Fire processContext server event //N.B. This is the pattern implemented in C++ and the event fires provisionally. //That is to say it may be many minutes between the event firing and the client request //actually arriving or the client may hang up without ever makeing a request. if (ServerEventHandler != null) { await ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken); } //Process client request (blocks until transport is readable) if (!await processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken)) { break; } } } catch (TTransportException) { //Usually a client disconnect, expected } catch (Exception x) { //Unexpected LogError("Error: " + x); } //Fire deleteContext server event after client disconnects if (ServerEventHandler != null) { await ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken); } } finally { //Close transports inputTransport?.Close(); outputTransport?.Close(); // disposable stuff should be disposed inputProtocol?.Dispose(); outputProtocol?.Dispose(); inputTransport?.Dispose(); outputTransport?.Dispose(); } }