Add HubConnection.State (#2204)

This commit is contained in:
James Newton-King 2018-05-14 19:23:00 +12:00 committed by GitHub
parent ffc665ccc2
commit 7625bbcb6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 0 deletions

View File

@ -58,6 +58,24 @@ namespace Microsoft.AspNetCore.SignalR.Client
public TimeSpan ServerTimeout { get; set; } = DefaultServerTimeout;
public TimeSpan HandshakeTimeout { get; set; } = DefaultHandshakeTimeout;
/// <summary>
/// Indicates the state of the <see cref="HubConnection"/> to the server.
/// </summary>
public HubConnectionState State
{
get
{
// Copy reference for thread-safety
var connectionState = _connectionState;
if (connectionState == null || connectionState.Stopped)
{
return HubConnectionState.Disconnected;
}
return HubConnectionState.Connected;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="HubConnection"/> class.
/// </summary>
@ -994,6 +1012,8 @@ namespace Microsoft.AspNetCore.SignalR.Client
set => _stopping = value;
}
public bool Stopped => _stopTcs?.Task.Status == TaskStatus.RanToCompletion;
public ConnectionState(ConnectionContext connection, HubConnection hubConnection)
{
_hubConnection = hubConnection;

View File

@ -0,0 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.SignalR.Client
{
/// <summary>
/// Describes the current state of the <see cref="HubConnection"/> to the server.
/// </summary>
public enum HubConnectionState
{
/// <summary>
/// The hub connection is disconnected.
/// </summary>
Disconnected,
/// <summary>
/// The hub connection is open.
/// </summary>
Connected
}
}

View File

@ -55,8 +55,11 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
var testConnection = new TestConnection();
await AsyncUsing(CreateHubConnection(testConnection), async connection =>
{
Assert.Equal(HubConnectionState.Disconnected, connection.State);
await connection.StartAsync();
Assert.True(testConnection.Started.IsCompleted);
Assert.Equal(HubConnectionState.Connected, connection.State);
});
}
@ -104,12 +107,18 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
await AsyncUsing(CreateHubConnection(ConnectionFactory, DisposeAsync), async connection =>
{
Assert.Equal(HubConnectionState.Disconnected, connection.State);
await connection.StartAsync().OrTimeout();
Assert.Equal(1, createCount);
Assert.Equal(HubConnectionState.Connected, connection.State);
await connection.StopAsync().OrTimeout();
Assert.Equal(HubConnectionState.Disconnected, connection.State);
await connection.StartAsync().OrTimeout();
Assert.Equal(2, createCount);
Assert.Equal(HubConnectionState.Connected, connection.State);
});
}
@ -216,6 +225,58 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
});
}
[Fact]
public async Task StatusIsNotConnectedUntilStartAsyncIsFinished()
{
// Set up StartAsync to wait on the syncPoint when starting
var testConnection = new TestConnection(onStart: SyncPoint.Create(out var syncPoint));
await AsyncUsing(CreateHubConnection(testConnection), async connection =>
{
// Start, and wait for the sync point to be hit
var startTask = connection.StartAsync().OrTimeout();
Assert.False(startTask.IsCompleted);
await syncPoint.WaitForSyncPoint();
Assert.Equal(HubConnectionState.Disconnected, connection.State);
// Release the SyncPoint
syncPoint.Continue();
// Wait for start to finish
await startTask;
Assert.Equal(HubConnectionState.Connected, connection.State);
});
}
[Fact]
public async Task StatusIsDisconnectedInCloseEvent()
{
var testConnection = new TestConnection();
await AsyncUsing(CreateHubConnection(testConnection), async connection =>
{
var closed = new TaskCompletionSource<object>();
connection.Closed += exception =>
{
closed.TrySetResult(null);
Assert.Equal(HubConnectionState.Disconnected, connection.State);
return Task.CompletedTask;
};
Assert.Equal(HubConnectionState.Disconnected, connection.State);
await connection.StartAsync().OrTimeout();
Assert.True(testConnection.Started.IsCompleted);
Assert.Equal(HubConnectionState.Connected, connection.State);
await connection.StopAsync().OrTimeout();
await testConnection.Disposed.OrTimeout();
Assert.Equal(HubConnectionState.Disconnected, connection.State);
await closed.Task.OrTimeout();
});
}
[Fact]
public async Task StopAsyncStopsConnection()
{
@ -247,13 +308,18 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
var testConnection = new TestConnection();
await AsyncUsing(CreateHubConnection(testConnection), async connection =>
{
Assert.Equal(HubConnectionState.Disconnected, connection.State);
await connection.StartAsync().OrTimeout();
Assert.True(testConnection.Started.IsCompleted);
Assert.Equal(HubConnectionState.Connected, connection.State);
await connection.StopAsync().OrTimeout();
await testConnection.Disposed.OrTimeout();
Assert.Equal(HubConnectionState.Disconnected, connection.State);
await connection.StopAsync().OrTimeout();
Assert.Equal(HubConnectionState.Disconnected, connection.State);
});
}
@ -396,6 +462,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
hubConnection.HandshakeTimeout = TimeSpan.FromMilliseconds(1);
await Assert.ThrowsAsync<OperationCanceledException>(() => hubConnection.StartAsync().OrTimeout());
Assert.Equal(HubConnectionState.Disconnected, hubConnection.State);
}
finally
{