Search code examples
c#azuresignalrsignalr-hubsignalr-backplane

How do I push data from a console program over SignalR websockets?


I have a website running as an Azure Web App which is configured to use SignalR and the Azure Service Bus scaleout backplane. All working well, and clients connect via the /signalr URL and I can push data from the server to the connected clients.

I also have several console apps which periodically run and output new data. I would also like to push the new data to the web-connected clients.

How can I tie in my non-web applications with SignalR? All the examples I see assume every server in the scaleout cluster are web-facing. Is there some special setup I need to do to have external processes join the SignalR cluster and be able to push data to web-connected clients over the SignalR websocket connection without having to make them web apps as well?


Solution

  • There are two options.

    First Option

    You can connect your "console apps" to the signalR backplane, and these apps will be able to call client's methods with something like

    var hub = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
    hub.Clients.All.doSomething("blah-blah");
    

    You can use any port for the signalR config but same backplane configuration and same Hubs. You can use Owin for self hosting. Nobody will connect to these console apps.

    Disadvantages:

    1) Your console applications needs to reference SignalR.SelfHosting and your hubs classes. This is not good from architecture point of view.

    2) Your console apps will listen some ports (since they're signalR servers). Theoretically somebody could connect to this hubs and do something. This is not good neither from architecture point of view no from security.

    Second Option

    You can implement Hub method like "PushSomeDataToClients" and call it from your console apps using SignalR client as mentioned in @bartbje comment.

    Pros: no disadvantages from the first option.

    Cons: You need to implement some security stuff to prevent anybody outside the system to call this method. SignalR has a lot of stuff to do this, so just google. For example you can create separate Hub for inter-system communications.

    Third Option

    Interact with web-server apps with another way then SignalR. Probably you're already using something like rabbitMq or any type of service bus. Also you can implement it using separate ApiController at your web-server app. But it seems to be closer to the second option.

    Due to me, I would probably choose the third option since it's clean from architecture point of view.