Remove the params argument from IClientProxy (#946)
* Remove the params argument from IClientProxy - This allows passing arrays without having to explicitly ToArray() or AsEnumerable() - Added overloads up to 10 arguments - Added tests
This commit is contained in:
parent
26255cc29c
commit
9df8d2f795
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace ChatSample.Hubs
|
||||
{
|
||||
|
|
@ -23,12 +24,12 @@ namespace ChatSample.Hubs
|
|||
|
||||
public override Task OnUsersJoined(UserDetails[] users)
|
||||
{
|
||||
return Clients.Client(Context.ConnectionId).InvokeAsync("UsersJoined", new[] { users });
|
||||
return Clients.Client(Context.ConnectionId).InvokeAsync("UsersJoined", users);
|
||||
}
|
||||
|
||||
public override Task OnUsersLeft(UserDetails[] users)
|
||||
{
|
||||
return Clients.Client(Context.ConnectionId).InvokeAsync("UsersLeft", new[] { users });
|
||||
return Clients.Client(Context.ConnectionId).InvokeAsync("UsersLeft", users);
|
||||
}
|
||||
|
||||
public async Task Send(string message)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,6 @@ namespace Microsoft.AspNetCore.SignalR
|
|||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="args">argumetns to pass to the client</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
Task InvokeAsync(string method, params object[] args);
|
||||
Task InvokeAsync(string method, object[] args);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,175 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.SignalR
|
||||
{
|
||||
public static class IClientProxyExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <param name="arg4">The fourth argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3, arg4 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <param name="arg4">The fourth argument</param>
|
||||
/// <param name="arg5">The fifth argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <param name="arg4">The fourth argument</param>
|
||||
/// <param name="arg5">The fifth argument</param>
|
||||
/// <param name="arg6">The sixth argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <param name="arg4">The fourth argument</param>
|
||||
/// <param name="arg5">The fifth argument</param>
|
||||
/// <param name="arg6">The sixth argument</param>
|
||||
/// <param name="arg7">The seventh argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <param name="arg4">The fourth argument</param>
|
||||
/// <param name="arg5">The fifth argument</param>
|
||||
/// <param name="arg6">The sixth argument</param>
|
||||
/// <param name="arg7">The seventh argument</param>
|
||||
/// <param name="arg8">The eigth argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <param name="arg4">The fourth argument</param>
|
||||
/// <param name="arg5">The fifth argument</param>
|
||||
/// <param name="arg6">The sixth argument</param>
|
||||
/// <param name="arg7">The seventh argument</param>
|
||||
/// <param name="arg8">The eigth argument</param>
|
||||
/// <param name="arg9">The ninth argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="clientProxy">The <see cref="IClientProxy"/></param>
|
||||
/// <param name="method">name of the method to invoke</param>
|
||||
/// <param name="arg1">The first argument</param>
|
||||
/// <param name="arg2">The second argument</param>
|
||||
/// <param name="arg3">The third argument</param>
|
||||
/// <param name="arg4">The fourth argument</param>
|
||||
/// <param name="arg5">The fifth argument</param>
|
||||
/// <param name="arg6">The sixth argument</param>
|
||||
/// <param name="arg7">The seventh argument</param>
|
||||
/// <param name="arg8">The eigth argument</param>
|
||||
/// <param name="arg9">The ninth argument</param>
|
||||
/// <param name="arg10">The tenth argument</param>
|
||||
/// <returns>A task that represents when the data has been sent to the client.</returns>
|
||||
public static Task InvokeAsync(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)
|
||||
{
|
||||
return clientProxy.InvokeAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ using Moq;
|
|||
using MsgPack;
|
||||
using MsgPack.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -697,6 +698,42 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SendArraySendsArrayToAllClients()
|
||||
{
|
||||
var serviceProvider = CreateServiceProvider();
|
||||
|
||||
var endPoint = serviceProvider.GetService<HubEndPoint<MethodHub>>();
|
||||
|
||||
using (var firstClient = new TestClient())
|
||||
using (var secondClient = new TestClient())
|
||||
{
|
||||
Task firstEndPointTask = endPoint.OnConnectedAsync(firstClient.Connection);
|
||||
Task secondEndPointTask = endPoint.OnConnectedAsync(secondClient.Connection);
|
||||
|
||||
await Task.WhenAll(firstClient.Connected, secondClient.Connected).OrTimeout();
|
||||
|
||||
await firstClient.SendInvocationAsync(nameof(MethodHub.SendArray)).OrTimeout();
|
||||
|
||||
foreach (var result in await Task.WhenAll(
|
||||
firstClient.ReadAsync(),
|
||||
secondClient.ReadAsync()).OrTimeout())
|
||||
{
|
||||
var invocation = Assert.IsType<InvocationMessage>(result);
|
||||
Assert.Equal("Array", invocation.Target);
|
||||
Assert.Single(invocation.Arguments);
|
||||
var values = ((JArray)invocation.Arguments[0]).Select(t => t.Value<int>()).ToArray();
|
||||
Assert.Equal(new int[] { 1, 2, 3 }, values);
|
||||
}
|
||||
|
||||
// kill the connections
|
||||
firstClient.Dispose();
|
||||
secondClient.Dispose();
|
||||
|
||||
await Task.WhenAll(firstEndPointTask, secondEndPointTask).OrTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(HubTypes))]
|
||||
public async Task SendToAllExcept(Type hubType)
|
||||
|
|
@ -1570,6 +1607,11 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
|||
return Clients.All.InvokeAsync("Broadcast", new Result { Message = "test", paramName = "param" });
|
||||
}
|
||||
|
||||
public Task SendArray()
|
||||
{
|
||||
return Clients.All.InvokeAsync("Array", new int[] { 1, 2, 3 });
|
||||
}
|
||||
|
||||
public Task<int> TaskValueMethod()
|
||||
{
|
||||
return Task.FromResult(42);
|
||||
|
|
|
|||
Loading…
Reference in New Issue