Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/SignalR/server/Core/src/Internal/HubClients`T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public HubClients(HubLifetimeManager<THub> lifetimeManager)

public T All { get; }

public T Single(string connectionId)
{
return TypedClientBuilder<T>.Build(new SingleClientProxyWithInvoke<THub>(_lifetimeManager, connectionId));
}

public T AllExcept(IReadOnlyList<string> excludedConnectionIds)
{
return TypedClientBuilder<T>.Build(new AllClientsExceptProxy<THub>(_lifetimeManager, excludedConnectionIds));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,8 @@ public interface Test
{
Task Send(string message);
Task Broadcast(string message);

Task<int> GetClientResult(int value);
}

public class OnConnectedThrowsHub : Hub
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,68 @@ public async Task ThrowsWhenParallelHubInvokesNotEnabled()
}
}
}

[Fact]
public async Task CanUseClientResultsWithIHubContext()
{
using (StartVerifiableLog())
{
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(null, LoggerFactory);
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<MethodHub>>();

using var client = new TestClient();

var connectionHandlerTask = await client.ConnectAsync(connectionHandler);

// Wait for a connection, or for the endpoint to fail.
await client.Connected.OrThrowIfOtherFails(connectionHandlerTask).DefaultTimeout();

var context = serviceProvider.GetRequiredService<IHubContext<MethodHub>>();
var resultTask = context.Clients.Single(client.Connection.ConnectionId).InvokeAsync<int>("GetClientResult", 1);

var message = await client.ReadAsync().DefaultTimeout();
var invocation = Assert.IsType<InvocationMessage>(message);

Assert.Single(invocation.Arguments);
Assert.Equal(1L, invocation.Arguments[0]);
Assert.Equal("GetClientResult", invocation.Target);

await client.SendHubMessageAsync(CompletionMessage.WithResult(invocation.InvocationId, 2)).DefaultTimeout();

var result = await resultTask.DefaultTimeout();
Assert.Equal(2, result);
}
}

[Fact]
public async Task CanUseClientResultsWithIHubContextT()
{
using (StartVerifiableLog())
{
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(null, LoggerFactory);
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<HubT>>();

using var client = new TestClient();

var connectionHandlerTask = await client.ConnectAsync(connectionHandler);

// Wait for a connection, or for the endpoint to fail.
await client.Connected.OrThrowIfOtherFails(connectionHandlerTask).DefaultTimeout();

var context = serviceProvider.GetRequiredService<IHubContext<HubT, Test>>();
var resultTask = context.Clients.Single(client.Connection.ConnectionId).GetClientResult(1);

var message = await client.ReadAsync().DefaultTimeout();
var invocation = Assert.IsType<InvocationMessage>(message);

Assert.Single(invocation.Arguments);
Assert.Equal(1L, invocation.Arguments[0]);
Assert.Equal("GetClientResult", invocation.Target);

await client.SendHubMessageAsync(CompletionMessage.WithResult(invocation.InvocationId, 2)).DefaultTimeout();

var result = await resultTask.DefaultTimeout();
Assert.Equal(2, result);
}
}
}