Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrennanConroy <brecon@microsoft.com>2021-06-24 23:35:22 +0300
committerBrennanConroy <brecon@microsoft.com>2021-06-24 23:35:22 +0300
commit6b2c37cd024296e9f7d405a31f5216dc0dcc201c (patch)
tree09ceae4df1dfdc81a487dc13f7b85c00c43aa986
parent7b28c2b572cf32cf3c874d637ca8337a3b459830 (diff)
Surface more connection closure issues to OnDisconnectedAsyncbrecon/surfaceex
-rw-r--r--src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs4
-rw-r--r--src/SignalR/common/Http.Connections/src/Internal/Transports/WebSocketsServerTransport.cs1
-rw-r--r--src/SignalR/common/Http.Connections/test/HttpConnectionDispatcherTests.cs6
-rw-r--r--src/SignalR/server/Core/src/HubConnectionContext.cs1
-rw-r--r--src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs43
5 files changed, 50 insertions, 5 deletions
diff --git a/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs b/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs
index 9e3c61e060..c0302ec581 100644
--- a/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs
+++ b/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs
@@ -156,8 +156,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
HttpConnectionsEventSource.Log.ConnectionTimedOut(connection.ConnectionId);
// This is most likely a long polling connection. The transport here ends because
- // a poll completed and has been inactive for > 5 seconds so we wait for the
+ // a poll completed and has been inactive for > 15 seconds so we wait for the
// application to finish gracefully
+ Debug.Assert(connection.TransportTask?.IsCompleted ?? true);
+ connection.TransportTask = Task.FromException(new TimeoutException("Connection timed out."));
_ = DisposeAndRemoveAsync(connection, closeGracefully: true);
}
else
diff --git a/src/SignalR/common/Http.Connections/src/Internal/Transports/WebSocketsServerTransport.cs b/src/SignalR/common/Http.Connections/src/Internal/Transports/WebSocketsServerTransport.cs
index ef0be3ae85..ad770d4996 100644
--- a/src/SignalR/common/Http.Connections/src/Internal/Transports/WebSocketsServerTransport.cs
+++ b/src/SignalR/common/Http.Connections/src/Internal/Transports/WebSocketsServerTransport.cs
@@ -180,6 +180,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal.Transports
{
// Client has closed the WebSocket connection without completing the close handshake
Log.ClosedPrematurely(_logger, ex);
+ _application.Output.Complete(ex);
}
catch (OperationCanceledException)
{
diff --git a/src/SignalR/common/Http.Connections/test/HttpConnectionDispatcherTests.cs b/src/SignalR/common/Http.Connections/test/HttpConnectionDispatcherTests.cs
index 08ecfd8e39..776357a8b3 100644
--- a/src/SignalR/common/Http.Connections/test/HttpConnectionDispatcherTests.cs
+++ b/src/SignalR/common/Http.Connections/test/HttpConnectionDispatcherTests.cs
@@ -520,9 +520,9 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
return async connectionContext =>
{
// Ensure both sides of the pipe are ok
- var result = await connectionContext.Transport.Input.ReadAsync();
- Assert.True(result.IsCompleted);
- await connectionContext.Transport.Output.WriteAsync(result.Buffer.First);
+ var ex = await Assert.ThrowsAsync<TimeoutException>(async () => await connectionContext.Transport.Input.ReadAsync());
+ Assert.Equal("Connection timed out.", ex.Message);
+ await connectionContext.Transport.Output.WriteAsync(new ReadOnlyMemory<byte>());
};
});
diff --git a/src/SignalR/server/Core/src/HubConnectionContext.cs b/src/SignalR/server/Core/src/HubConnectionContext.cs
index dcb55cab3d..916db19fb2 100644
--- a/src/SignalR/server/Core/src/HubConnectionContext.cs
+++ b/src/SignalR/server/Core/src/HubConnectionContext.cs
@@ -664,6 +664,7 @@ namespace Microsoft.AspNetCore.SignalR
if (_receivedMessageElapsedTicks >= _clientTimeoutInterval)
{
Log.ClientTimeout(_logger, TimeSpan.FromTicks(_clientTimeoutInterval));
+ CloseException = new TimeoutException("Client timeout elapsed without receiving a message from the client.");
AbortAllowReconnect();
}
}
diff --git a/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs b/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs
index 63429b83dc..b849b5f27f 100644
--- a/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs
+++ b/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs
@@ -2788,7 +2788,10 @@ namespace Microsoft.AspNetCore.SignalR.Tests
var clock = new MockSystemClock();
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(services =>
services.Configure<HubOptions>(options =>
- options.ClientTimeoutInterval = TimeSpan.FromMilliseconds(timeout)), LoggerFactory);
+ {
+ options.ClientTimeoutInterval = TimeSpan.FromMilliseconds(timeout);
+ options.EnableDetailedErrors = true;
+ }), LoggerFactory);
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<MethodHub>>();
connectionHandler.SystemClock = clock;
@@ -2801,12 +2804,50 @@ namespace Microsoft.AspNetCore.SignalR.Tests
clock.UtcNow = clock.UtcNow.AddMilliseconds(timeout + 1);
client.TickHeartbeat();
+ var closeMessage = Assert.IsType<CloseMessage>(await client.ReadAsync().DefaultTimeout());
+ Assert.True(closeMessage.AllowReconnect);
+ Assert.Equal("Connection closed with an error. TimeoutException: Client timeout elapsed without receiving a message from the client.", closeMessage.Error);
await connectionHandlerTask.DefaultTimeout();
}
}
}
[Fact]
+ public async Task TimeoutPassesExceptionToOnDisconnectedAsync()
+ {
+ using (StartVerifiableLog())
+ {
+ var timeout = 100;
+ var clock = new MockSystemClock();
+ var state = new ConnectionLifetimeState();
+ var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(services =>
+ {
+ services.Configure<HubOptions>(options =>
+ {
+ options.ClientTimeoutInterval = TimeSpan.FromMilliseconds(timeout);
+ options.EnableDetailedErrors = true;
+ });
+ services.AddSingleton(state);
+ }, LoggerFactory);
+ var connectionHandler = serviceProvider.GetService<HubConnectionHandler<ConnectionLifetimeHub>>();
+ connectionHandler.SystemClock = clock;
+
+ using (var client = new TestClient())
+ {
+ var connectionHandlerTask = await client.ConnectAsync(connectionHandler);
+ await client.SendHubMessageAsync(PingMessage.Instance);
+
+ clock.UtcNow = clock.UtcNow.AddMilliseconds(timeout + 1);
+ client.TickHeartbeat();
+
+ await connectionHandlerTask.DefaultTimeout();
+
+ Assert.IsType<TimeoutException>(state.DisconnectedException);
+ }
+ }
+ }
+
+ [Fact]
public async Task ReceivingMessagesPreventsConnectionTimeoutFromOccuring()
{
using (StartVerifiableLog())