Beispiel #1
0
    private async Task HandleAsync(TcpClient tcpClient)
    {
        string connectionDetails;

        try
        {
            connectionDetails = tcpClient.Client.RemoteEndPoint?.ToString() ?? "No details";
        }
        catch (Exception exception)
        {
            connectionDetails = "Failed to get details";
            _logger.LogError(exception, "Failed to get connection details.");
        }

        try
        {
            using var stream      = tcpClient.GetStream();
            using var sendLock    = new SemaphoreSlimLock();
            using var receiveLock = new SemaphoreSlimLock();
            var connection = _protobufConnectionFactory.CreateProtobufConnection(stream)
                             .WithLocking(sendLock, receiveLock);

            var task = _connectionHandler
                       .HandleAsync(connection, _cts.Token)
                       .HandleCancellationAsync(exception =>
            {
                _logger.LogDebug(
                    exception,
                    "Cancellation request received for client: {ConnectionDetails}",
                    connectionDetails);
            })
                       .HandleExceptionAsync <Exception>(exception =>
            {
                _logger.LogError(
                    exception,
                    "Error happened while handling TCP connection: {ConnectionDetails}",
                    connectionDetails);
            });

            _connectionProcessors.Add(task);
            _connectionProcessors.RemoveAll(t => t.IsCompleted);

            await task.ConfigureAwait(false);
        }
#pragma warning disable CA1031 // This method should not throw ANY exceptions, it is a top-level handler.
        catch (Exception exception)
#pragma warning restore CA1031
        {
            _logger.LogError(
                exception,
                "Error happened while creating TCP connection: {ConnectionDetails}",
                connectionDetails);
        }
        finally
        {
            tcpClient.Dispose();
        }
    }
    public async ValueTask <ConnectionWithDisconnect> ConnectAsync(CancellationToken cancellationToken)
    {
        var client = new TcpClient();
        await client.ConnectAsync(_host, _port, cancellationToken).ConfigureAwait(false);

        var stream      = client.GetStream();
        var sendLock    = new SemaphoreSlimLock();
        var receiveLock = new SemaphoreSlimLock();
        var connection  = _factory.CreateProtobufConnection(stream)
                          .WithLocking(sendLock, receiveLock);

        return(new ConnectionWithDisconnect(connection, async() =>
        {
            receiveLock.Dispose();
            sendLock.Dispose();
            stream.Close();

            await stream.DisposeAsync().ConfigureAwait(false);
            client.Dispose();
        }));
    }