1
votes

Following scenario: I've got a ASP.NET Web Api running a SignalR hub, serving a SPA. The SignalR hub is used to communicate with several C# SignalR clients. Now I want to retrieve data from a specific client and return this data from the Web API Controller to the web client. Please see my sample below:

    public async Task<IHttpActionResult> Get()
    {
        Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<Hubs.ConfigHub>().Clients.Client("SomeConnectionId").getData();
        // SignalR client is calling a callback method on the SignalR hub hosted in the web api
        // return data;
     }

Is there any way how I can achieve this?

1
What's your actual issue? The code (your abstraction of it, anyway) looks good to me - Mark C.
The problem is that I need the client to return data before i return data from the web api controller. - Vince Black

1 Answers

2
votes

You can´t retrieve client data from the server hub. That´s a SignalR missing feature.

The server can only invoke commands on the client but it can´t await for any response, so Clients.Client("SomeConnectionId").getData() won´t ever return anything. Only clients are able to do that.

There is not easy path to do it. This is what I would do to solve the situation:

public async Task<IHttpActionResult> Get()
{
    Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager
        .GetHubContext<Hubs.ConfigHub>()
        .Clients.Client("SomeConnectionId")
        .PleaseSendYourDataToTheHub();

     // don´t return anything and don´t await for results on the web client. 
     // The client just needs a 200 (ok) response to be sure the request 
     // is sent and going on.
 }

Clients would "listen" for that command (PleaseSendYourDataToTheHub) and then call the corresponding method in the hub.

In your hub you would have a method like:

public void OnClientData(DataType data)
{
    // TODO find out the web client connection id 
    // send the data to the web client
    Clients.Client("webClientConnectionId")
        .DataFromClient(clientId, data);
}

Then, in the web client, you would listen to a proxy event like:

proxy.on('DataFromClient', function(clientId, data) {
    // do something with the data
});