locked
Calling a SignalR Hub From Azure WebJobs RRS feed

  • Question

  • Is it feasible to call a SignalR Hub From Azure WebJobs? I have the following:

    var _hubConnection = new HubConnection("http://custom_name.azure-mobile.net");
    _hubConnection.Headers["x-zumo-application"] = "our mobile key";
    var _proxy = await _hubConnection.CreateHubProxy("NotificationsHub");
    await _hubConnection.Start();
    await _proxy.Invoke<string>("Send", "message");

    System.InvalidOperationException: The connection has not been established. at Microsoft.AspNet.SignalR.Client.Connection.Send(String data) at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke[TResult,TProgress](String method, Action`1 onProgress, Object[] args) at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke[T](String method, Object[] args) at ...


    Monday, June 22, 2015 9:04 PM

Answers

All replies

  • Hello TimJohnson1,

    Signal R hubs can be called using the Azure Webjobs. You can refer to the link below that shows demonstration on building a SiteMonitorR using Azure Webjobs:
    http://www.bradygaster.com/post/rebuilding-the-sitemonitr-using-windows-azure-webjobs

    You can also refer the the sample code:
    http://code.msdn.microsoft.com/SiteMonitR-dd4fcf77

    Also the error message indicates that you will need to call start before invoke. You can refer to the thread below: Refer to the response from halter72 that shows how to call SignalR:

    http://stackoverflow.com/questions/15581802/cannot-open-signalr-connection-in-silverlight-client

    Thanks,
    Syed Irfan Hussain

    Tuesday, June 23, 2015 4:57 AM
  • If you're using SignalR with a backplane (e.g. Redis Cache) to scale out across multiple servers, it seems like it would be preferable to have the WebJob communicate directly with the backplane, instead of communicating with one of the web servers via HTTP.

    The approach shown in that article you link to doesn't work that way. In fact it really has nothing to do with WebJobs - it just has the web app expose an endpoint that sends a SignalR message on behalf of whatever client hits that endpoint, whether it's a WebJob or something else. In a single-server scenario this is the right way to do it, because that's the only way to get the message data into SignalR. But in a multi-server scenario with a message bus backplane, the approach shown in that article adds what seems like unnecessary overhead. Sending a message will work like this:

    1. WebJob sends the message to the HTTP endpoint exposed by the web app
    2. The web app sends the message to the SignalR message bus backplane (e.g. Redis Cache)
    3. The backplane delivers the message to all the web servers in the server farm
    4. Each servers works out whether it has any connected clients that should receive this message, and if so, delivers the message to them.

    But if the WebJob were able to connect directly to the backplane (and in principle, there's no reason it can't), it would instead look like this:

    1. WebJob sends the the message to the SignalR message bus backplane (e.g. Redis Cache)
    2. The backplane delivers the message to all the web servers in the server farm
    3. Each servers works out whether it has any connected clients that should receive this message, and if so, delivers the message to them.

    This avoids an unnecessary extra HTTP round trip to the web app server, so it would reduce latency and it would reduce CPU load on the web farm. And it also avoids the need to arrange some means by which the WebJob can authenticate itself with the web server. (Brady's example doesn't bother with this - the endpoint that the WebJob hits is unsecured, meaning that anyone with knowledge of the relevant URL could spoof requests from the WebJob. I've not actually seen any good examples that solve this problem when using this technique.)

    So the only question is: is there a supported way to do this? I suspect there isn't because I don't think the SignalR libraries are supported for use outside of an ASP.NET app.

    Tuesday, September 13, 2016 9:37 AM