private async Task <IpcResponse> GetResponseAsync(IpcRequest request, CancellationToken cancellationToken) { using (Stream client = await ConnectToServerAsync(cancellationToken)) using (var writer = new IpcWriter(client, _serializer, leaveOpen: true)) using (var reader = new IpcReader(client, _serializer, leaveOpen: true)) { // send request await writer.WriteAsync(request, cancellationToken).ConfigureAwait(false); // receive response return(await reader.ReadIpcResponseAsync(cancellationToken).ConfigureAwait(false)); } }
private async Task ProcessAsync(Stream server, CancellationToken stoppingToken) { if (stoppingToken.IsCancellationRequested) { return; } if (_options.StreamTranslator != null) { server = _options.StreamTranslator(server); } using (var writer = new IpcWriter(server, _options.Serializer, leaveOpen: true)) using (var reader = new IpcReader(server, _options.Serializer, leaveOpen: true)) using (IDisposable loggingScope = _logger.BeginScope(new Dictionary <string, object> { { "threadId", Thread.CurrentThread.ManagedThreadId } })) { try { IpcRequest request; try { _logger.LogDebug($"Client connected, reading request..."); request = await reader.ReadIpcRequestAsync(stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.BadRequest, "Failed to deserialize request.", ex); } stoppingToken.ThrowIfCancellationRequested(); IpcResponse response; try { _logger.LogDebug($"Request received, invoking '{request.MethodName}'..."); using (IServiceScope scope = _serviceProvider.CreateScope()) { response = await GetReponseAsync(request, scope).ConfigureAwait(false); } } catch (Exception ex) when(!(ex is IpcException)) { throw new IpcFaultException(IpcStatus.InternalServerError, "Unexpected exception raised from user code", ex); } stoppingToken.ThrowIfCancellationRequested(); try { _logger.LogDebug($"Sending response..."); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.InternalServerError, "Failed to serialize response.", ex); } _logger.LogDebug($"Process finished."); } catch (IpcCommunicationException ex) { _logger.LogError(ex, "Communication error occurred."); // if communication error occurred, client will probably not receive any response } catch (OperationCanceledException ex) { _logger.LogWarning(ex, "IPC request process cancelled"); IpcResponse response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError("IPC request process cancelled") : IpcResponse.InternalServerError(); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcFaultException ex) { _logger.LogError(ex, "Failed to process IPC request."); IpcResponse response; switch (ex.Status) { case IpcStatus.BadRequest: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.BadRequest(ex.Message, ex.InnerException) : IpcResponse.BadRequest(); break; default: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError(ex.Message, ex.InnerException) : IpcResponse.InternalServerError(); break; } await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } } }
private async Task ProcessAsync(Stream server, string clientIdentifier, CancellationToken stoppingToken) { if (stoppingToken.IsCancellationRequested) { return; } if (_options.StreamTranslator != null) { server = _options.StreamTranslator(server); } using (var writer = new IpcWriter(server, _options.Serializer, leaveOpen: true)) using (var reader = new IpcReader(server, _options.Serializer, leaveOpen: true)) using (IDisposable loggingScope = _logger.BeginScope(new Dictionary <string, object> { { "threadId", Thread.CurrentThread.ManagedThreadId } })) { try { IpcRequest request; try { // Log first connection if loglevel >= information. // Log every connection if loglevel <= debug. string message = $"Client connected from {clientIdentifier}."; if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug(message); } else if (!_knownConections.ContainsKey(clientIdentifier)) { Logger.LogInformation(message); _knownConections[clientIdentifier] = true; } request = await reader.ReadIpcRequestAsync(stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.BadRequest, "Failed to deserialize request.", ex); } stoppingToken.ThrowIfCancellationRequested(); IpcResponse response; try { string parameters = (request.Parameters == null) ? "None" : string.Join(",", request.Parameters); var paramTypes = (request.ParameterTypesByName == null) ? ((request.ParameterTypes == null) ? "None" : string.Join(", ", request.ParameterTypes)) : string.Join(", ", request.ParameterTypesByName.Select(x => x.ParameterType)); _logger.LogDebug($"Request received, invoking '{request.MethodName}' Params '{parameters}' Types '{paramTypes}'..."); using (IServiceScope scope = _serviceProvider.CreateScope()) { response = await GetReponseAsync(request, scope).ConfigureAwait(false); } } catch (Exception ex) when(!(ex is IpcException)) { throw new IpcFaultException(IpcStatus.InternalServerError, "Unexpected exception raised from user code", ex); } stoppingToken.ThrowIfCancellationRequested(); try { _logger.LogTrace($"Sending response for '{request.MethodName}'..."); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcSerializationException ex) { throw new IpcFaultException(IpcStatus.InternalServerError, "Failed to serialize response.", ex); } _logger.LogTrace($"Process finished for '{request.MethodName}'."); } catch (IpcCommunicationException ex) { _logger.LogError(ex, "Communication error occurred."); // if communication error occurred, client will probably not receive any response } catch (OperationCanceledException ex) { _logger.LogWarning(ex, "IPC request process cancelled"); IpcResponse response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError("IPC request process cancelled") : IpcResponse.InternalServerError(); await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } catch (IpcFaultException ex) { if (ex.Status != IpcStatus.InternalServerError || _options.LogInternalServerErrors) { _logger.LogError(ex, "Failed to process IPC request."); } IpcResponse response; switch (ex.Status) { case IpcStatus.BadRequest: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.BadRequest(ex.Message, ex.InnerException) : IpcResponse.BadRequest(); break; default: response = _options.IncludeFailureDetailsInResponse ? IpcResponse.InternalServerError(ex.Message, ex.InnerException) : IpcResponse.InternalServerError(); break; } await writer.WriteAsync(response, stoppingToken).ConfigureAwait(false); } } }