Remove handlers from HubConnection (#2267)

This commit is contained in:
Mikael Mengistu 2018-05-15 23:57:02 -07:00 committed by GitHub
parent 9cb683a41d
commit 283297f455
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 0 deletions

View File

@ -171,6 +171,9 @@ namespace Microsoft.AspNetCore.SignalR.Client
private static readonly Action<ILogger, string, string, Exception> _argumentBindingFailure =
LoggerMessage.Define<string, string>(LogLevel.Error, new EventId(57, "ArgumentBindingFailure"), "Failed to bind arguments received in invocation '{InvocationId}' of '{MethodName}'.");
private static readonly Action<ILogger, string, Exception> _removingHandlers =
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(58, "RemovingHandlers"), "Removing handlers for client method '{MethodName}'.");
public static void PreparingNonBlockingInvocation(ILogger logger, string target, int count)
{
_preparingNonBlockingInvocation(logger, target, count, null);
@ -360,6 +363,11 @@ namespace Microsoft.AspNetCore.SignalR.Client
_registeringHandler(logger, methodName, null);
}
public static void RemovingHandlers(ILogger logger, string methodName)
{
_removingHandlers(logger, methodName, null);
}
public static void Starting(ILogger logger)
{
_starting(logger, null);

View File

@ -175,6 +175,16 @@ namespace Microsoft.AspNetCore.SignalR.Client
return new Subscription(invocationHandler, invocationList);
}
/// <summary>
/// Removes all handlers associated with the method with the specified method name.
/// </summary>
/// <param name="methodName">The name of the hub method from which handlers are being removed</param>
public void Remove(string methodName)
{
CheckDisposed();
Log.RemovingHandlers(_logger, methodName);
_handlers.TryRemove(methodName, out _);
}
/// <summary>
/// Invokes a streaming hub method on the server using the specified method name, return type and arguments.

View File

@ -379,6 +379,72 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
}
}
[Fact]
public async Task HandlerIsRemovedProperlyWithOff()
{
var connection = new TestConnection();
var hubConnection = CreateHubConnection(connection);
var handlerCalled = new TaskCompletionSource<int>();
try
{
await hubConnection.StartAsync().OrTimeout();
hubConnection.On<int>("Foo", (val) =>
{
handlerCalled.TrySetResult(val);
});
hubConnection.Remove("Foo");
await connection.ReceiveJsonMessage(new { invocationId = "1", type = 1, target = "Foo", arguments = 1 }).OrTimeout();
var handlerTask = handlerCalled.Task;
// We expect the handler task to timeout since the handler has been removed with the call to Remove("Foo")
var ex = Assert.ThrowsAsync<TimeoutException>(async () => await handlerTask.OrTimeout(2000));
// Ensure that the task from the WhenAny is not the handler task
Assert.False(handlerCalled.Task.IsCompleted);
}
finally
{
await hubConnection.DisposeAsync().OrTimeout();
await connection.DisposeAsync().OrTimeout();
}
}
[Fact]
public async Task DisposingSubscriptionAfterCallingRemoveHandlerDoesntFail()
{
var connection = new TestConnection();
var hubConnection = CreateHubConnection(connection);
var handlerCalled = new TaskCompletionSource<int>();
try
{
await hubConnection.StartAsync().OrTimeout();
var subscription = hubConnection.On<int>("Foo", (val) =>
{
handlerCalled.TrySetResult(val);
});
hubConnection.Remove("Foo");
await connection.ReceiveJsonMessage(new { invocationId = "1", type = 1, target = "Foo", arguments = 1 }).OrTimeout();
var handlerTask = handlerCalled.Task;
subscription.Dispose();
// We expect the handler task to timeout since the handler has been removed with the call to Remove("Foo")
var ex = Assert.ThrowsAsync<TimeoutException>(async () => await handlerTask.OrTimeout(2000));
// Ensure that the task from the WhenAny is not the handler task
Assert.False(handlerCalled.Task.IsCompleted);
}
finally
{
await hubConnection.DisposeAsync().OrTimeout();
await connection.DisposeAsync().OrTimeout();
}
}
[Fact]
public async Task AcceptsPingMessages()
{