Merge pull request #2122 from aspnet/release/2.1
CancellationToken EVERYWHERE (#2101)
This commit is contained in:
commit
d5f62f7b5a
|
|
@ -6,6 +6,7 @@ using System.Buffers;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Pipelines;
|
using System.IO.Pipelines;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
|
|
@ -82,7 +83,7 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ValueTask WriteAsync(HubMessage message)
|
public override ValueTask WriteAsync(HubMessage message, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (message is CompletionMessage completionMessage)
|
if (message is CompletionMessage completionMessage)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ClientSample;
|
using ClientSample;
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
|
|
@ -46,7 +47,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
_endPoint = endPoint;
|
_endPoint = endPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat)
|
public Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return new TcpConnection(_endPoint).StartAsync();
|
return new TcpConnection(_endPoint).StartAsync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,12 +121,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
|
||||||
_transportFactory = transportFactory;
|
_transportFactory = transportFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartAsync()
|
public async Task StartAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await StartAsync(TransferFormat.Binary);
|
await StartAsync(TransferFormat.Binary, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartAsync(TransferFormat transferFormat)
|
public async Task StartAsync(TransferFormat transferFormat, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await StartAsyncCore(transferFormat).ForceAsync();
|
await StartAsyncCore(transferFormat).ForceAsync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Http.Connections;
|
|
||||||
using Microsoft.AspNetCore.Http.Connections.Internal;
|
using Microsoft.AspNetCore.Http.Connections.Internal;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Http.Connections.Internal;
|
using Microsoft.AspNetCore.Http.Connections.Internal;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http.Connections.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Http.Connections
|
namespace Microsoft.AspNetCore.Http.Connections
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Http.Connections
|
namespace Microsoft.AspNetCore.Http.Connections
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@ using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Connections.Features;
|
using Microsoft.AspNetCore.Connections.Features;
|
||||||
using Microsoft.AspNetCore.Internal;
|
using Microsoft.AspNetCore.Internal;
|
||||||
using Microsoft.AspNetCore.SignalR.Client.Internal;
|
using Microsoft.AspNetCore.SignalR.Client.Internal;
|
||||||
using Microsoft.AspNetCore.SignalR.Internal;
|
|
||||||
using Microsoft.AspNetCore.SignalR.Protocol;
|
using Microsoft.AspNetCore.SignalR.Protocol;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
|
||||||
|
|
@ -78,6 +76,8 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
await StopAsyncCore(disposing: false).ForceAsync();
|
await StopAsyncCore(disposing: false).ForceAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Current plan for IAsyncDisposable is that DisposeAsync will NOT take a CancellationToken
|
||||||
|
// https://github.com/dotnet/csharplang/blob/195efa07806284d7b57550e7447dc8bd39c156bf/proposals/async-streams.md#iasyncdisposable
|
||||||
public async Task DisposeAsync()
|
public async Task DisposeAsync()
|
||||||
{
|
{
|
||||||
if (!_disposed)
|
if (!_disposed)
|
||||||
|
|
@ -211,7 +211,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
// Now stop the connection we captured
|
// Now stop the connection we captured
|
||||||
if (connectionState != null)
|
if (connectionState != null)
|
||||||
{
|
{
|
||||||
await connectionState.StopAsync(ServerTimeout);
|
await connectionState.StopAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -970,7 +970,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StopAsync(TimeSpan timeout)
|
public Task StopAsync()
|
||||||
{
|
{
|
||||||
// We want multiple StopAsync calls on the same connection state
|
// We want multiple StopAsync calls on the same connection state
|
||||||
// to wait for the same "stop" to complete.
|
// to wait for the same "stop" to complete.
|
||||||
|
|
@ -983,12 +983,12 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_stopTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
_stopTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
return StopAsyncCore(timeout);
|
return StopAsyncCore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StopAsyncCore(TimeSpan timeout)
|
private async Task StopAsyncCore()
|
||||||
{
|
{
|
||||||
Log.Stopping(_hubConnection._logger);
|
Log.Stopping(_hubConnection._logger);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Connections;
|
|
||||||
using Microsoft.AspNetCore.SignalR.Protocol;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Client
|
namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Client
|
namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Client
|
namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading.Channels;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Client
|
namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
|
|
||||||
|
|
@ -8,8 +9,10 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
{
|
{
|
||||||
public interface IConnectionFactory
|
public interface IConnectionFactory
|
||||||
{
|
{
|
||||||
Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat);
|
Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
// Current plan for IAsyncDisposable is that DisposeAsync will NOT take a CancellationToken
|
||||||
|
// https://github.com/dotnet/csharplang/blob/195efa07806284d7b57550e7447dc8bd39c156bf/proposals/async-streams.md#iasyncdisposable
|
||||||
Task DisposeAsync(ConnectionContext connection);
|
Task DisposeAsync(ConnectionContext connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Http.Connections.Client;
|
using Microsoft.AspNetCore.Http.Connections.Client;
|
||||||
|
|
@ -31,10 +32,10 @@ namespace Microsoft.AspNetCore.SignalR.Client
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat)
|
public async Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var connection = new HttpConnection(_httpConnectionOptions, _loggerFactory);
|
var connection = new HttpConnection(_httpConnectionOptions, _loggerFactory);
|
||||||
await connection.StartAsync(transferFormat);
|
await connection.StartAsync(transferFormat, cancellationToken);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
using System.Collections.Generic;
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
using System.Text;
|
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR
|
namespace Microsoft.AspNetCore.SignalR
|
||||||
|
|
@ -13,10 +15,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||||
/// <param name="method">name of the method to invoke</param>
|
/// <param name="method">name of the method to invoke</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, Array.Empty<object>());
|
return clientProxy.SendCoreAsync(method, Array.Empty<object>(), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -26,10 +29,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||||
/// <param name="method">name of the method to invoke</param>
|
/// <param name="method">name of the method to invoke</param>
|
||||||
/// <param name="arg1">The first argument</param>
|
/// <param name="arg1">The first argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -40,10 +44,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="method">name of the method to invoke</param>
|
/// <param name="method">name of the method to invoke</param>
|
||||||
/// <param name="arg1">The first argument</param>
|
/// <param name="arg1">The first argument</param>
|
||||||
/// <param name="arg2">The second argument</param>
|
/// <param name="arg2">The second argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -55,10 +60,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg1">The first argument</param>
|
/// <param name="arg1">The first argument</param>
|
||||||
/// <param name="arg2">The second argument</param>
|
/// <param name="arg2">The second argument</param>
|
||||||
/// <param name="arg3">The third argument</param>
|
/// <param name="arg3">The third argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -71,10 +77,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg2">The second argument</param>
|
/// <param name="arg2">The second argument</param>
|
||||||
/// <param name="arg3">The third argument</param>
|
/// <param name="arg3">The third argument</param>
|
||||||
/// <param name="arg4">The fourth argument</param>
|
/// <param name="arg4">The fourth argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -88,10 +95,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg3">The third argument</param>
|
/// <param name="arg3">The third argument</param>
|
||||||
/// <param name="arg4">The fourth argument</param>
|
/// <param name="arg4">The fourth argument</param>
|
||||||
/// <param name="arg5">The fifth argument</param>
|
/// <param name="arg5">The fifth argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -106,10 +114,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg4">The fourth argument</param>
|
/// <param name="arg4">The fourth argument</param>
|
||||||
/// <param name="arg5">The fifth argument</param>
|
/// <param name="arg5">The fifth argument</param>
|
||||||
/// <param name="arg6">The sixth argument</param>
|
/// <param name="arg6">The sixth argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -125,10 +134,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg5">The fifth argument</param>
|
/// <param name="arg5">The fifth argument</param>
|
||||||
/// <param name="arg6">The sixth argument</param>
|
/// <param name="arg6">The sixth argument</param>
|
||||||
/// <param name="arg7">The seventh argument</param>
|
/// <param name="arg7">The seventh argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -145,10 +155,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg6">The sixth argument</param>
|
/// <param name="arg6">The sixth argument</param>
|
||||||
/// <param name="arg7">The seventh argument</param>
|
/// <param name="arg7">The seventh argument</param>
|
||||||
/// <param name="arg8">The eigth argument</param>
|
/// <param name="arg8">The eigth argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -166,10 +177,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg7">The seventh argument</param>
|
/// <param name="arg7">The seventh argument</param>
|
||||||
/// <param name="arg8">The eigth argument</param>
|
/// <param name="arg8">The eigth argument</param>
|
||||||
/// <param name="arg9">The ninth argument</param>
|
/// <param name="arg9">The ninth argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -188,10 +200,11 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// <param name="arg8">The eigth argument</param>
|
/// <param name="arg8">The eigth argument</param>
|
||||||
/// <param name="arg9">The ninth argument</param>
|
/// <param name="arg9">The ninth argument</param>
|
||||||
/// <param name="arg10">The tenth argument</param>
|
/// <param name="arg10">The tenth argument</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10)
|
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
|
return clientProxy.SendCoreAsync(method, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.SignalR.Internal;
|
using Microsoft.AspNetCore.SignalR.Internal;
|
||||||
using Microsoft.AspNetCore.SignalR.Protocol;
|
using Microsoft.AspNetCore.SignalR.Protocol;
|
||||||
|
|
@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task AddToGroupAsync(string connectionId, string groupName)
|
public override Task AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (connectionId == null)
|
if (connectionId == null)
|
||||||
{
|
{
|
||||||
|
|
@ -46,7 +47,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task RemoveFromGroupAsync(string connectionId, string groupName)
|
public override Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (connectionId == null)
|
if (connectionId == null)
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +70,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendAllAsync(string methodName, object[] args)
|
public override Task SendAllAsync(string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return SendToAllConnections(methodName, args, null);
|
return SendToAllConnections(methodName, args, null);
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +146,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendConnectionAsync(string connectionId, string methodName, object[] args)
|
public override Task SendConnectionAsync(string connectionId, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (connectionId == null)
|
if (connectionId == null)
|
||||||
{
|
{
|
||||||
|
|
@ -166,7 +167,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
return connection.WriteAsync(message).AsTask();
|
return connection.WriteAsync(message).AsTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendGroupAsync(string groupName, string methodName, object[] args)
|
public override Task SendGroupAsync(string groupName, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (groupName == null)
|
if (groupName == null)
|
||||||
{
|
{
|
||||||
|
|
@ -191,7 +192,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object[] args)
|
public override Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// Each task represents the list of tasks for each of the writes within a group
|
// Each task represents the list of tasks for each of the writes within a group
|
||||||
List<Task> tasks = null;
|
List<Task> tasks = null;
|
||||||
|
|
@ -219,7 +220,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds)
|
public override Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (groupName == null)
|
if (groupName == null)
|
||||||
{
|
{
|
||||||
|
|
@ -253,7 +254,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
return new InvocationMessage(methodName, args);
|
return new InvocationMessage(methodName, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendUserAsync(string userId, string methodName, object[] args)
|
public override Task SendUserAsync(string userId, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return SendToAllConnections(methodName, args, connection => string.Equals(connection.UserIdentifier, userId, StringComparison.Ordinal));
|
return SendToAllConnections(methodName, args, connection => string.Equals(connection.UserIdentifier, userId, StringComparison.Ordinal));
|
||||||
}
|
}
|
||||||
|
|
@ -271,17 +272,17 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds)
|
public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return SendToAllConnections(methodName, args, connection => !excludedConnectionIds.Contains(connection.ConnectionId));
|
return SendToAllConnections(methodName, args, connection => !excludedConnectionIds.Contains(connection.ConnectionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object[] args)
|
public override Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return SendToAllConnections(methodName, args, connection => connectionIds.Contains(connection.ConnectionId));
|
return SendToAllConnections(methodName, args, connection => connectionIds.Contains(connection.ConnectionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object[] args)
|
public override Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return SendToAllConnections(methodName, args, connection => userIds.Contains(connection.UserIdentifier));
|
return SendToAllConnections(methodName, args, connection => userIds.Contains(connection.UserIdentifier));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
// Currently used only for streaming methods
|
// Currently used only for streaming methods
|
||||||
internal ConcurrentDictionary<string, CancellationTokenSource> ActiveRequestCancellationSources { get; } = new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.Ordinal);
|
internal ConcurrentDictionary<string, CancellationTokenSource> ActiveRequestCancellationSources { get; } = new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.Ordinal);
|
||||||
|
|
||||||
public virtual ValueTask WriteAsync(HubMessage message)
|
public virtual ValueTask WriteAsync(HubMessage message, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// Try to grab the lock synchronously, if we fail, go to the slower path
|
// Try to grab the lock synchronously, if we fail, go to the slower path
|
||||||
if (!_writeLock.Wait(0))
|
if (!_writeLock.Wait(0))
|
||||||
|
|
@ -92,8 +92,9 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// connection.
|
/// connection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The serialization cache to use.</param>
|
/// <param name="message">The serialization cache to use.</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual ValueTask WriteAsync(SerializedHubMessage message)
|
public virtual ValueTask WriteAsync(SerializedHubMessage message, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// Try to grab the lock synchronously, if we fail, go to the slower path
|
// Try to grab the lock synchronously, if we fail, go to the slower path
|
||||||
if (!_writeLock.Wait(0))
|
if (!_writeLock.Wait(0))
|
||||||
|
|
|
||||||
|
|
@ -2,37 +2,40 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR
|
namespace Microsoft.AspNetCore.SignalR
|
||||||
{
|
{
|
||||||
public abstract class HubLifetimeManager<THub> where THub : Hub
|
public abstract class HubLifetimeManager<THub> where THub : Hub
|
||||||
{
|
{
|
||||||
|
// Called by the framework and not something we'd cancel, so it doesn't take a cancellation token
|
||||||
public abstract Task OnConnectedAsync(HubConnectionContext connection);
|
public abstract Task OnConnectedAsync(HubConnectionContext connection);
|
||||||
|
|
||||||
|
// Called by the framework and not something we'd cancel, so it doesn't take a cancellation token
|
||||||
public abstract Task OnDisconnectedAsync(HubConnectionContext connection);
|
public abstract Task OnDisconnectedAsync(HubConnectionContext connection);
|
||||||
|
|
||||||
public abstract Task SendAllAsync(string methodName, object[] args);
|
public abstract Task SendAllAsync(string methodName, object[] args, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds);
|
public abstract Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendConnectionAsync(string connectionId, string methodName, object[] args);
|
public abstract Task SendConnectionAsync(string connectionId, string methodName, object[] args, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object[] args);
|
public abstract Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object[] args, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendGroupAsync(string groupName, string methodName, object[] args);
|
public abstract Task SendGroupAsync(string groupName, string methodName, object[] args, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object[] args);
|
public abstract Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object[] args, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds);
|
public abstract Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendUserAsync(string userId, string methodName, object[] args);
|
public abstract Task SendUserAsync(string userId, string methodName, object[] args, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object[] args);
|
public abstract Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object[] args, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task AddToGroupAsync(string connectionId, string groupName);
|
public abstract Task AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
public abstract Task RemoveFromGroupAsync(string connectionId, string groupName);
|
public abstract Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR
|
namespace Microsoft.AspNetCore.SignalR
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR
|
namespace Microsoft.AspNetCore.SignalR
|
||||||
|
|
@ -17,7 +18,8 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="method">Name of the method to invoke.</param>
|
/// <param name="method">Name of the method to invoke.</param>
|
||||||
/// <param name="args">A collection of arguments to pass to the client.</param>
|
/// <param name="args">A collection of arguments to pass to the client.</param>
|
||||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
|
||||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||||
Task SendCoreAsync(string method, object[] args);
|
Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR
|
namespace Microsoft.AspNetCore.SignalR
|
||||||
{
|
{
|
||||||
public interface IGroupManager
|
public interface IGroupManager
|
||||||
{
|
{
|
||||||
Task AddToGroupAsync(string connectionId, string groupName);
|
Task AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default);
|
||||||
Task RemoveFromGroupAsync(string connectionId, string groupName);
|
Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
|
{
|
||||||
|
internal class GroupManager<THub> : IGroupManager where THub : Hub
|
||||||
|
{
|
||||||
|
private readonly HubLifetimeManager<THub> _lifetimeManager;
|
||||||
|
|
||||||
|
public GroupManager(HubLifetimeManager<THub> lifetimeManager)
|
||||||
|
{
|
||||||
|
_lifetimeManager = lifetimeManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return _lifetimeManager.AddToGroupAsync(connectionId, groupName, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return _lifetimeManager.RemoveFromGroupAsync(connectionId, groupName, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Internal
|
namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
|
|
@ -17,9 +18,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_userId = userId;
|
_userId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendUserAsync(_userId, method, args);
|
return _lifetimeManager.SendUserAsync(_userId, method, args, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,9 +35,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_userIds = userIds;
|
_userIds = userIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendUsersAsync(_userIds, method, args);
|
return _lifetimeManager.SendUsersAsync(_userIds, method, args, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,9 +52,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_groupName = groupName;
|
_groupName = groupName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendGroupAsync(_groupName, method, args);
|
return _lifetimeManager.SendGroupAsync(_groupName, method, args, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,9 +69,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_groupNames = groupNames;
|
_groupNames = groupNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendGroupsAsync(_groupNames, method, args);
|
return _lifetimeManager.SendGroupsAsync(_groupNames, method, args, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,9 +88,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_excludedConnectionIds = excludedConnectionIds;
|
_excludedConnectionIds = excludedConnectionIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendGroupExceptAsync(_groupName, method, args, _excludedConnectionIds);
|
return _lifetimeManager.SendGroupExceptAsync(_groupName, method, args, _excludedConnectionIds, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +103,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_lifetimeManager = lifetimeManager;
|
_lifetimeManager = lifetimeManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendAllAsync(method, args);
|
return _lifetimeManager.SendAllAsync(method, args);
|
||||||
}
|
}
|
||||||
|
|
@ -119,9 +120,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_excludedConnectionIds = excludedConnectionIds;
|
_excludedConnectionIds = excludedConnectionIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendAllExceptAsync(method, args, _excludedConnectionIds);
|
return _lifetimeManager.SendAllExceptAsync(method, args, _excludedConnectionIds, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,9 +137,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_connectionId = connectionId;
|
_connectionId = connectionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendConnectionAsync(_connectionId, method, args);
|
return _lifetimeManager.SendConnectionAsync(_connectionId, method, args, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,29 +154,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
_connectionIds = connectionIds;
|
_connectionIds = connectionIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return _lifetimeManager.SendConnectionsAsync(_connectionIds, method, args);
|
return _lifetimeManager.SendConnectionsAsync(_connectionIds, method, args, cancellationToken);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class GroupManager<THub> : IGroupManager where THub : Hub
|
|
||||||
{
|
|
||||||
private readonly HubLifetimeManager<THub> _lifetimeManager;
|
|
||||||
|
|
||||||
public GroupManager(HubLifetimeManager<THub> lifetimeManager)
|
|
||||||
{
|
|
||||||
_lifetimeManager = lifetimeManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task AddToGroupAsync(string connectionId, string groupName)
|
|
||||||
{
|
|
||||||
return _lifetimeManager.AddToGroupAsync(connectionId, groupName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task RemoveFromGroupAsync(string connectionId, string groupName)
|
|
||||||
{
|
|
||||||
return _lifetimeManager.RemoveFromGroupAsync(connectionId, groupName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Internal
|
namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
|
|
@ -17,6 +18,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
// There is one static instance of _builder per T
|
// There is one static instance of _builder per T
|
||||||
private static readonly Lazy<Func<IClientProxy, T>> _builder = new Lazy<Func<IClientProxy, T>>(() => GenerateClientBuilder());
|
private static readonly Lazy<Func<IClientProxy, T>> _builder = new Lazy<Func<IClientProxy, T>>(() => GenerateClientBuilder());
|
||||||
|
|
||||||
|
private static readonly PropertyInfo CancellationTokenNoneProperty = typeof(CancellationToken).GetProperty("None", BindingFlags.Public | BindingFlags.Static);
|
||||||
|
|
||||||
public static T Build(IClientProxy proxy)
|
public static T Build(IClientProxy proxy)
|
||||||
{
|
{
|
||||||
return _builder.Value(proxy);
|
return _builder.Value(proxy);
|
||||||
|
|
@ -115,7 +118,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
|
|
||||||
var invokeMethod = typeof(IClientProxy).GetMethod(
|
var invokeMethod = typeof(IClientProxy).GetMethod(
|
||||||
nameof(IClientProxy.SendCoreAsync), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
|
nameof(IClientProxy.SendCoreAsync), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
|
||||||
new[] { typeof(string), typeof(object[]) }, null);
|
new[] { typeof(string), typeof(object[]), typeof(CancellationToken) }, null);
|
||||||
|
|
||||||
methodBuilder.SetReturnType(interfaceMethodInfo.ReturnType);
|
methodBuilder.SetReturnType(interfaceMethodInfo.ReturnType);
|
||||||
methodBuilder.SetParameters(paramTypes);
|
methodBuilder.SetParameters(paramTypes);
|
||||||
|
|
@ -156,8 +159,13 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
generator.Emit(OpCodes.Stelem_Ref);
|
generator.Emit(OpCodes.Stelem_Ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call SendCoreAsync
|
// Load parameter array on to the stack.
|
||||||
generator.Emit(OpCodes.Ldloc_0);
|
generator.Emit(OpCodes.Ldloc_0);
|
||||||
|
|
||||||
|
// Get 'CancellationToken.None' and put it on the stack, since we don't support CancellationToken right now
|
||||||
|
generator.Emit(OpCodes.Call, CancellationTokenNoneProperty.GetMethod);
|
||||||
|
|
||||||
|
// Send!
|
||||||
generator.Emit(OpCodes.Callvirt, invokeMethod);
|
generator.Emit(OpCodes.Callvirt, invokeMethod);
|
||||||
|
|
||||||
generator.Emit(OpCodes.Ret); // Return the Task returned by 'invokeMethod'
|
generator.Emit(OpCodes.Ret); // Return the Task returned by 'invokeMethod'
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.SignalR.Internal;
|
|
||||||
using Microsoft.AspNetCore.SignalR.Protocol;
|
using Microsoft.AspNetCore.SignalR.Protocol;
|
||||||
using Microsoft.AspNetCore.SignalR.Redis.Internal;
|
using Microsoft.AspNetCore.SignalR.Redis.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
@ -106,19 +105,19 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
return Task.WhenAll(tasks);
|
return Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendAllAsync(string methodName, object[] args)
|
public override Task SendAllAsync(string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var message = _protocol.WriteInvocation(methodName, args);
|
var message = _protocol.WriteInvocation(methodName, args);
|
||||||
return PublishAsync(_channels.All, message);
|
return PublishAsync(_channels.All, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds)
|
public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var message = _protocol.WriteInvocation(methodName, args, excludedConnectionIds);
|
var message = _protocol.WriteInvocation(methodName, args, excludedConnectionIds);
|
||||||
return PublishAsync(_channels.All, message);
|
return PublishAsync(_channels.All, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendConnectionAsync(string connectionId, string methodName, object[] args)
|
public override Task SendConnectionAsync(string connectionId, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (connectionId == null)
|
if (connectionId == null)
|
||||||
{
|
{
|
||||||
|
|
@ -137,7 +136,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
return PublishAsync(_channels.Connection(connectionId), message);
|
return PublishAsync(_channels.Connection(connectionId), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendGroupAsync(string groupName, string methodName, object[] args)
|
public override Task SendGroupAsync(string groupName, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (groupName == null)
|
if (groupName == null)
|
||||||
{
|
{
|
||||||
|
|
@ -148,7 +147,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
return PublishAsync(_channels.Group(groupName), message);
|
return PublishAsync(_channels.Group(groupName), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds)
|
public override async Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (groupName == null)
|
if (groupName == null)
|
||||||
{
|
{
|
||||||
|
|
@ -159,13 +158,13 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
await PublishAsync(_channels.Group(groupName), message);
|
await PublishAsync(_channels.Group(groupName), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendUserAsync(string userId, string methodName, object[] args)
|
public override Task SendUserAsync(string userId, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var message = _protocol.WriteInvocation(methodName, args);
|
var message = _protocol.WriteInvocation(methodName, args);
|
||||||
return PublishAsync(_channels.User(userId), message);
|
return PublishAsync(_channels.User(userId), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task AddToGroupAsync(string connectionId, string groupName)
|
public override async Task AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (connectionId == null)
|
if (connectionId == null)
|
||||||
{
|
{
|
||||||
|
|
@ -188,7 +187,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
await SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Add);
|
await SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Add);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task RemoveFromGroupAsync(string connectionId, string groupName)
|
public override async Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (connectionId == null)
|
if (connectionId == null)
|
||||||
{
|
{
|
||||||
|
|
@ -211,7 +210,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
await SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Remove);
|
await SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object[] args)
|
public override Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (connectionIds == null)
|
if (connectionIds == null)
|
||||||
{
|
{
|
||||||
|
|
@ -229,7 +228,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
return Task.WhenAll(publishTasks);
|
return Task.WhenAll(publishTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object[] args)
|
public override Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (groupNames == null)
|
if (groupNames == null)
|
||||||
{
|
{
|
||||||
|
|
@ -249,7 +248,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
return Task.WhenAll(publishTasks);
|
return Task.WhenAll(publishTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object[] args)
|
public override Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object[] args, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (userIds.Count > 0)
|
if (userIds.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.SignalR.Internal;
|
using Microsoft.AspNetCore.SignalR.Internal;
|
||||||
|
|
@ -62,7 +63,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
await manager2.OnConnectedAsync(connection2).OrTimeout();
|
await manager2.OnConnectedAsync(connection2).OrTimeout();
|
||||||
await manager3.OnConnectedAsync(connection3).OrTimeout();
|
await manager3.OnConnectedAsync(connection3).OrTimeout();
|
||||||
|
|
||||||
await manager1.SendAllExceptAsync("Hello", new object[] { "World" }, new [] { client3.Connection.ConnectionId }).OrTimeout();
|
await manager1.SendAllExceptAsync("Hello", new object[] { "World" }, new[] { client3.Connection.ConnectionId }).OrTimeout();
|
||||||
|
|
||||||
await AssertMessageAsync(client1);
|
await AssertMessageAsync(client1);
|
||||||
await AssertMessageAsync(client2);
|
await AssertMessageAsync(client2);
|
||||||
|
|
@ -455,7 +456,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
{
|
{
|
||||||
// Force an exception when writing to connection
|
// Force an exception when writing to connection
|
||||||
var connectionMock = HubConnectionContextUtils.CreateMock(client.Connection);
|
var connectionMock = HubConnectionContextUtils.CreateMock(client.Connection);
|
||||||
connectionMock.Setup(m => m.WriteAsync(It.IsAny<HubMessage>())).Throws(new Exception());
|
connectionMock.Setup(m => m.WriteAsync(It.IsAny<HubMessage>(), It.IsAny<CancellationToken>())).Throws(new Exception());
|
||||||
var connection = connectionMock.Object;
|
var connection = connectionMock.Object;
|
||||||
|
|
||||||
await manager2.OnConnectedAsync(connection).OrTimeout();
|
await manager2.OnConnectedAsync(connection).OrTimeout();
|
||||||
|
|
@ -478,7 +479,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests
|
||||||
{
|
{
|
||||||
// Force an exception when writing to connection
|
// Force an exception when writing to connection
|
||||||
var connectionMock = HubConnectionContextUtils.CreateMock(client1.Connection);
|
var connectionMock = HubConnectionContextUtils.CreateMock(client1.Connection);
|
||||||
connectionMock.Setup(m => m.WriteAsync(It.IsAny<HubMessage>())).Throws(new Exception());
|
connectionMock.Setup(m => m.WriteAsync(It.IsAny<HubMessage>(), It.IsAny<CancellationToken>())).Throws(new Exception());
|
||||||
|
|
||||||
var connection1 = connectionMock.Object;
|
var connection1 = connectionMock.Object;
|
||||||
var connection2 = HubConnectionContextUtils.Create(client2.Connection);
|
var connection2 = HubConnectionContextUtils.Create(client2.Connection);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
|
@ -13,13 +14,14 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
private readonly Func<TransferFormat, Task<ConnectionContext>> _connectDelegate;
|
private readonly Func<TransferFormat, Task<ConnectionContext>> _connectDelegate;
|
||||||
private readonly Func<ConnectionContext, Task> _disposeDelegate;
|
private readonly Func<ConnectionContext, Task> _disposeDelegate;
|
||||||
|
|
||||||
|
// We have no tests that use the CancellationToken. When we do, we can add it to the delegate. This is test code.
|
||||||
public DelegateConnectionFactory(Func<TransferFormat, Task<ConnectionContext>> connectDelegate, Func<ConnectionContext, Task> disposeDelegate)
|
public DelegateConnectionFactory(Func<TransferFormat, Task<ConnectionContext>> connectDelegate, Func<ConnectionContext, Task> disposeDelegate)
|
||||||
{
|
{
|
||||||
_connectDelegate = connectDelegate;
|
_connectDelegate = connectDelegate;
|
||||||
_disposeDelegate = disposeDelegate;
|
_disposeDelegate = disposeDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat)
|
public Task<ConnectionContext> ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return _connectDelegate(transferFormat);
|
return _connectDelegate(transferFormat);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.SignalR.Internal;
|
using Microsoft.AspNetCore.SignalR.Internal;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
|
@ -22,8 +23,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendUserAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>()))
|
o.Setup(m => m.SendUserAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<string, string, object[]>((userId, methodName, args) => { resultArgs = args; })
|
.Callback<string, string, object[], CancellationToken>((userId, methodName, args, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new UserProxy<FakeHub>(o.Object, string.Empty);
|
var proxy = new UserProxy<FakeHub>(o.Object, string.Empty);
|
||||||
|
|
@ -43,8 +44,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendUsersAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>()))
|
o.Setup(m => m.SendUsersAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<IReadOnlyList<string>, string, object[]>((userIds, methodName, args) => { resultArgs = args; })
|
.Callback<IReadOnlyList<string>, string, object[], CancellationToken>((userIds, methodName, args, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new MultipleUserProxy<FakeHub>(o.Object, new List<string>());
|
var proxy = new MultipleUserProxy<FakeHub>(o.Object, new List<string>());
|
||||||
|
|
@ -64,8 +65,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendGroupAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>()))
|
o.Setup(m => m.SendGroupAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<string, string, object[]>((groupName, methodName, args) => { resultArgs = args; })
|
.Callback<string, string, object[], CancellationToken>((groupName, methodName, args, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new GroupProxy<FakeHub>(o.Object, string.Empty);
|
var proxy = new GroupProxy<FakeHub>(o.Object, string.Empty);
|
||||||
|
|
@ -85,8 +86,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendGroupsAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>()))
|
o.Setup(m => m.SendGroupsAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<IReadOnlyList<string>, string, object[]>((groupNames, methodName, args) => { resultArgs = args; })
|
.Callback<IReadOnlyList<string>, string, object[], CancellationToken>((groupNames, methodName, args, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new MultipleGroupProxy<FakeHub>(o.Object, new List<string>());
|
var proxy = new MultipleGroupProxy<FakeHub>(o.Object, new List<string>());
|
||||||
|
|
@ -106,8 +107,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendGroupExceptAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<IReadOnlyList<string>>()))
|
o.Setup(m => m.SendGroupExceptAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<IReadOnlyList<string>>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<string, string, object[], IReadOnlyList<string>>((groupName, methodName, args, excludedConnectionIds) => { resultArgs = args; })
|
.Callback<string, string, object[], IReadOnlyList<string>, CancellationToken>((groupName, methodName, args, excludedConnectionIds, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new GroupExceptProxy<FakeHub>(o.Object, string.Empty, new List<string>());
|
var proxy = new GroupExceptProxy<FakeHub>(o.Object, string.Empty, new List<string>());
|
||||||
|
|
@ -127,8 +128,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendAllAsync(It.IsAny<string>(), It.IsAny<object[]>()))
|
o.Setup(m => m.SendAllAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<string, object[]>((methodName, args) => { resultArgs = args; })
|
.Callback<string, object[], CancellationToken>((methodName, args, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new AllClientProxy<FakeHub>(o.Object);
|
var proxy = new AllClientProxy<FakeHub>(o.Object);
|
||||||
|
|
@ -148,8 +149,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendAllExceptAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<IReadOnlyList<string>>()))
|
o.Setup(m => m.SendAllExceptAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<IReadOnlyList<string>>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<string, object[], IReadOnlyList<string>>((methodName, args, excludedConnectionIds) => { resultArgs = args; })
|
.Callback<string, object[], IReadOnlyList<string>, CancellationToken>((methodName, args, excludedConnectionIds, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new AllClientsExceptProxy<FakeHub>(o.Object, new List<string>());
|
var proxy = new AllClientsExceptProxy<FakeHub>(o.Object, new List<string>());
|
||||||
|
|
@ -169,8 +170,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendConnectionAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>()))
|
o.Setup(m => m.SendConnectionAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<string, string, object[]>((connectionId, methodName, args) => { resultArgs = args; })
|
.Callback<string, string, object[], CancellationToken>((connectionId, methodName, args, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new SingleClientProxy<FakeHub>(o.Object, string.Empty);
|
var proxy = new SingleClientProxy<FakeHub>(o.Object, string.Empty);
|
||||||
|
|
@ -190,8 +191,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
object[] resultArgs = null;
|
object[] resultArgs = null;
|
||||||
|
|
||||||
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
var o = new Mock<HubLifetimeManager<FakeHub>>();
|
||||||
o.Setup(m => m.SendConnectionsAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>()))
|
o.Setup(m => m.SendConnectionsAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()))
|
||||||
.Callback<IReadOnlyList<string>, string, object[]>((connectionIds, methodName, args) => { resultArgs = args; })
|
.Callback<IReadOnlyList<string>, string, object[], CancellationToken>((connectionIds, methodName, args, _) => { resultArgs = args; })
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var proxy = new MultipleClientProxy<FakeHub>(o.Object, new List<string>());
|
var proxy = new MultipleClientProxy<FakeHub>(o.Object, new List<string>());
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Internal
|
||||||
Assert.Equal("Method", send.Method);
|
Assert.Equal("Method", send.Method);
|
||||||
Assert.Equal("foo", send.Arguments[0]);
|
Assert.Equal("foo", send.Arguments[0]);
|
||||||
Assert.Equal(42, send.Arguments[1]);
|
Assert.Equal(42, send.Arguments[1]);
|
||||||
|
Assert.Equal(CancellationToken.None, send.CancellationToken);
|
||||||
Assert.Same(objArg, send.Arguments[2]);
|
Assert.Same(objArg, send.Arguments[2]);
|
||||||
send.Complete();
|
send.Complete();
|
||||||
});
|
});
|
||||||
|
|
@ -58,6 +59,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Internal
|
||||||
arg1 => Assert.Equal("foo", arg1),
|
arg1 => Assert.Equal("foo", arg1),
|
||||||
arg2 => Assert.Equal(42, arg2),
|
arg2 => Assert.Equal(42, arg2),
|
||||||
arg3 => Assert.Same(objArg, arg3));
|
arg3 => Assert.Same(objArg, arg3));
|
||||||
|
Assert.Equal(CancellationToken.None, send1.CancellationToken);
|
||||||
send1.Complete();
|
send1.Complete();
|
||||||
},
|
},
|
||||||
send2 =>
|
send2 =>
|
||||||
|
|
@ -65,6 +67,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Internal
|
||||||
Assert.Equal("SubMethod", send2.Method);
|
Assert.Equal("SubMethod", send2.Method);
|
||||||
Assert.Collection(send2.Arguments,
|
Assert.Collection(send2.Arguments,
|
||||||
arg1 => Assert.Equal("bar", arg1));
|
arg1 => Assert.Equal("bar", arg1));
|
||||||
|
Assert.Equal(CancellationToken.None, send2.CancellationToken);
|
||||||
send2.Complete();
|
send2.Complete();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -190,11 +193,11 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Internal
|
||||||
{
|
{
|
||||||
public IList<SendContext> Sends { get; } = new List<SendContext>();
|
public IList<SendContext> Sends { get; } = new List<SendContext>();
|
||||||
|
|
||||||
public Task SendCoreAsync(string method, object[] args)
|
public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<object>();
|
var tcs = new TaskCompletionSource<object>();
|
||||||
|
|
||||||
Sends.Add(new SendContext(method, args, tcs));
|
Sends.Add(new SendContext(method, args, cancellationToken, tcs));
|
||||||
|
|
||||||
return tcs.Task;
|
return tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
@ -206,11 +209,13 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Internal
|
||||||
|
|
||||||
public string Method { get; }
|
public string Method { get; }
|
||||||
public object[] Arguments { get; }
|
public object[] Arguments { get; }
|
||||||
|
public CancellationToken CancellationToken { get; }
|
||||||
|
|
||||||
public SendContext(string method, object[] arguments, TaskCompletionSource<object> tcs) : this()
|
public SendContext(string method, object[] arguments, CancellationToken cancellationToken, TaskCompletionSource<object> tcs) : this()
|
||||||
{
|
{
|
||||||
Method = method;
|
Method = method;
|
||||||
Arguments = arguments;
|
Arguments = arguments;
|
||||||
|
CancellationToken = cancellationToken;
|
||||||
_tcs = tcs;
|
_tcs = tcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue