示例#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();
        }
    }
示例#2
0
    private async Task HandleAsync(HubCallerContext context, IClientProxy caller)
    {
        string connectionDetails;

        try
        {
            connectionDetails = $"{context.ConnectionId}, {context.UserIdentifier}, {context.User.Identity?.Name}";
        }
        catch (Exception exception)
        {
            connectionDetails = "Failed to get details";
            _logger.LogError(exception, "Failed to get connection details.");
        }

        try
        {
            using var localCts    = new CancellationTokenSource();
            using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(
                      _cts.Token, localCts.Token);

            var notificator = new Notificator();
            var connection  = _signalRConnectionFactory.CreateProtobufConnectionForServer(caller, notificator);

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

            var resource = new SignalRConnectionResource(
                notificator,
                async() =>
            {
                localCts.Cancel();
                await task.ConfigureAwait(false);
            });

            _notificators.TryAdd(context.ConnectionId, resource);

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

            await task.ConfigureAwait(false);

            // Warning: when exception is thrown inside the task, cancellation token is not canceled (only disposed).
            await resource.CancelAsync().ConfigureAwait(false);
        }
        catch (Exception exception)
        {
            _logger.LogError(
                exception,
                "Error happened when creating or handling SignalR connection: {ConnectionDetails}",
                connectionDetails);
        }
        finally
        {
            // Disconnect the client from the server side.
            context.Abort();

            _notificators.TryRemove(context.ConnectionId, out _);
        }
    }
示例#3
0
        private async Task HandleAsync(HubCallerContext context, IClientProxy caller)
        {
            string connectionDetails;

            try
            {
                connectionDetails = $"{context.ConnectionId}, {context.UserIdentifier}, {context.User.Identity?.Name}";
            }
            catch (Exception exception)
            {
                connectionDetails = "Failed to get details";
                _logger.LogError(exception, "Failed to get connection details.");
            }

            try
            {
                using var localCts    = new CancellationTokenSource();
                using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(
                          _cts.Token, localCts.Token);

                var notificator = new Notificator();
                var connection  = new SignalRMessageSender(caller)
                                  .WithNotificator(notificator)
                                  .WithJson(_jsonConnectionFactory)
                                  .WithReceiveAcknowledgement();

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

                var resource = new SignalRConnectionResource(
                    notificator,
                    async() =>
                {
                    localCts.Cancel();
                    await task.ConfigureAwait(false);
                });

                _notificators.TryAdd(context.ConnectionId, resource);

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

                await task.ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, $"Error happened when creating SignalR connection: {connectionDetails}");
            }
            finally
            {
                _notificators.TryRemove(context.ConnectionId, out _);
            }
        }