diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs b/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs index 015bf22846..f8c33e051f 100644 --- a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs +++ b/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs @@ -314,8 +314,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal connection.Status = HttpConnectionStatus.Inactive; - // Dispose the cancellation token - connection.Cancellation?.Dispose(); + connection.Cancellation?.Cancel(); connection.Cancellation = null; } diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs index 14a2fa6ac4..09288f5a30 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs @@ -515,6 +515,7 @@ namespace Microsoft.AspNetCore.SignalR { if (!_receivedMessageThisInterval) { + Log.ClientTimeout(_logger, TimeSpan.FromTicks(_clientTimeoutInterval)); Abort(); } @@ -573,6 +574,9 @@ namespace Microsoft.AspNetCore.SignalR private static readonly Action _abortFailed = LoggerMessage.Define(LogLevel.Trace, new EventId(8, "AbortFailed"), "Abort callback failed."); + private static readonly Action _clientTimeout = + LoggerMessage.Define(LogLevel.Debug, new EventId(9, "ClientTimeout"), "Client timeout ({ClientTimeout}ms) elapsed without receiving a message from the client. Closing connection."); + public static void HandshakeComplete(ILogger logger, string hubProtocol) { _handshakeComplete(logger, hubProtocol, null); @@ -612,6 +616,11 @@ namespace Microsoft.AspNetCore.SignalR { _abortFailed(logger, exception); } + + public static void ClientTimeout(ILogger logger, TimeSpan timeout) + { + _clientTimeout(logger, (int)timeout.TotalMilliseconds, null); + } } } } diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs index 6062003ce7..fc91abb899 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs @@ -118,10 +118,11 @@ namespace Microsoft.AspNetCore.SignalR.Tests Assert.Equal(bytes, buffer.Array.AsSpan(0, result.Count).ToArray()); logger.LogInformation("Closing socket"); - await ws.CloseOutputAsync(WebSocketCloseStatus.Empty, "", CancellationToken.None).OrTimeout(); + await ws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None).OrTimeout(); logger.LogInformation("Waiting for close"); result = await ws.ReceiveAsync(buffer, CancellationToken.None).OrTimeout(); Assert.Equal(WebSocketMessageType.Close, result.MessageType); + Assert.Equal(WebSocketCloseStatus.NormalClosure, result.CloseStatus); logger.LogInformation("Closed socket"); } } @@ -156,10 +157,11 @@ namespace Microsoft.AspNetCore.SignalR.Tests Assert.Equal(bytes, buffer.Array.AsSpan(0, result.Count).ToArray()); logger.LogInformation("Closing socket"); - await ws.CloseOutputAsync(WebSocketCloseStatus.Empty, "", CancellationToken.None).OrTimeout(); + await ws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None).OrTimeout(); logger.LogInformation("Waiting for close"); result = await ws.ReceiveAsync(buffer, CancellationToken.None).OrTimeout(); Assert.Equal(WebSocketMessageType.Close, result.MessageType); + Assert.Equal(WebSocketCloseStatus.NormalClosure, result.CloseStatus); logger.LogInformation("Closed socket"); } }