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(); } }
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 _); } }
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 _); } }