private async Task <IpcResponse> GetResponseAsync(IpcRequest request)
        {
            using (Stream client = await ConnectToServerAsync())
                using (var writer = new IpcWriter(client, _serializer, leaveOpen: true))
                    using (var reader = new IpcReader(client, _serializer, leaveOpen: true))
                    {
                        // send request
                        writer.Write(request);

                        // receive response
                        return(reader.ReadIpcResponse());
                    }
        }
Пример #2
0
        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));
                    }
        }
Пример #3
0
        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);
                        }
                    }
        }
Пример #4
0
        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);
                        }
                    }
        }