signalrsignalr-hubsignalr-backplane

SignalR simple gateway


I have a web application composed of a gateway and several back-end services. The gateway is a self-hosted OWIN application, and covers concerns like authentication, authorization, and routing of api calls to the backend.

I'm interested in using SignalR in one of my backend services to push data to the client. E.g. the user starts a long running query, and data is fed back to the client as it becomes available.

I managed to use the backplane from the scale-out article as a messaging mechanism (though it seems it wasn't designed for such messaging) SignalR scaleout explanation

"Gateway" Hub code: (The logic is only for testing purposes)

    public override async Task OnConnected()
    {
        HttpClient client = new HttpClient()
        {
            BaseAddress = new Uri("http://localhost:8888/other/")
        };

        var result = await client.PostAsJsonAsync("signin", Context.ConnectionId);

        await base.OnConnected();
    }

Backend controller code

    [HttpPost]
    [Route("signin")]
    public void PostSignin([FromBody]string id)
    {
        StartPing(id);
    }

    public async Task StartPing(string id)
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<FrontendHub>();

        int i = 0;
        while (true)
        {
            i++;
            context.Clients.Client(id).showMessage("num " + i);
            await Task.Delay(1000);
        }
    }

However, this is a big enterprise application, and I don't want the gateway to have any dependency on the actual code of the backend services. But the example only works if a hub with the same name is defined in both the gateway and the backend service.

On one hand, I'm trying to avoid the need to place such specialized code in the gateway, on the other hand, I'd like to leverage the ability to use actual function names and parameters. I don't want a "master hub" with a single function.

Is there a way to do it?


Solution

  • Didn't end up doing it all, but the solution discovered later was to indeed use a "Master hub", but it doesn't actually need to have any functions at all.

    The contract is between the backend service and the client application. Since everything in SignalR is loosely typed, it's enough that the client define some function on the hub, and the backend service invoke the same function on the hub. The hub doesn't actually need this function in its own code.