Simplify your realtime applications by bringing SignalR into the @ngrx ecosystem

David Bottiau
3 min readJul 29, 2019

--

You may have written realtime applications with SignalR and/or you also may have written a web application using the @ngrx ecosystem. Following the Redux pattern, you desire predictable state management but the asynchronous messaging system of SignalR cannot be a part of it. However, these kinds of operations can be handled with side effects. And of course, @ngrx can deal with it.

By bringing SignalR to your @ngrx/store and your @ngrx/effect, you gain control over your application in different way:

  • automatically create, connect, send/receive events and reconnect your SignalR hubs…
  • …to have a perfect state in sync with your hub statuses
  • …and so reuse this state to perform operations : detect offline/online mode, display hub status

Getting started

Of course, you’ll need the required packages that are @ngrx/store, @ngrx/effect and @aspnet/signalr.

npm install rxjs @ngrx/store @ngrx/effects @aspnet/signalr

And then, install the new dependency:

npm install ngrx-signalr-core

Once you have every dependency installed, do not forget to update your module:

To get started, you need two things:

  • a part of the state dedicated to save hubs definition with their respective status
  • and a list of predefined effects we will see right now

The thing you’ll never need to do : managing your hub lifecycle

There is at least 3 things we do for you that you’ll never need to do anymore when working with SignalR in an @ngrx app.

createHub$

createHub$ is a side effect that will automatically handle hub creation when you will execute the createSignalRHub action. Simply dispatch this action and a new hub will pop up instantly. Magic!

beforeStartHub$

In the side effect world, nothing will work as you expect. That’s why the beforeStartHub$ is made. It handles all the connection state effects for you:

  • when the hub fail to start
  • when the hub get disconnected (and connected then)
  • when any error occur

startHub$

And finally, startHub$ starts the hub when you dispatch a startSignalRHub action.

Automatic reconnection

Earlier, I said “at least 3 things we do for you”. Indeed, we provide a 4th effect that you can reuse as is. It is made for automatic reconnection since SignalR does not provide a reconnection mechanism.

You will have to add this effect inside your app:

Of course, this effect is provided to help developers with their most common scenarii. If you need a more complex reconnection mechanism like an exponential timer pattern, feel free to create your own effect.

The remaining fun part : event handling

Once everything is set up, you know want to use SignalR for what it is made: sending and receiving messages. We will use effects for that.

A single hub

All your event listeners must be done before starting the hub. That’s why when a hub is created (SIGNALR_HUB_UNSTARTED is dispatched), you can invoke the hub.on function to dispatch new action coming from the SignalR events.

Also, do not forget to start the signalr hub by dispatching a startSignalRHub action to receive messages.

You may also need to send events to the server using the hub.send function.

Dealing with multiple hubs

When writing your applications, you may have to use multiple hubs.

When dealing with multiple hubs, you can filter hub action by using the ofHub operator. So every effect that you will write will only be applied to the according hub.

Imagining you have multiple hubs:

Here is how to initialize hubs one by one:

Status report

Some of your actions have an impact on the state. As I said earlier, the state is in sync with the different hubs in the application. We have the hub status in realtime.

And of course, every hub status is inside the state:

Tell me, am I online?

We provide actions, we provide effects, we provide a state but we also provide some selectors that could fit your needs.

If I want to display a status information about whether the application is connected or not, I can use the selectors like this:

Using the connectionState$ observable, we can observe the current status of my application:

  • GREEN is all hubs are connected
  • RED when no internet connection or any hub disconnected
  • no status if hubs are unstarted for example

More information

This article demonstrates how to use SignalR (.NET Core) within a @ngrx application. If you want more details, you can check the GitHub repository here: https://github.com/Odonno/ngrx-signalr-core

Also, since SignalR implementation between .NET Core and .NET Framework is different, you can check the following repository to apply SignalR .NET Framework inside a @ngrx app: https://github.com/Odonno/ngrx-signalr

--

--

David Bottiau

Software designer, open-minded, Lean being and UX advocate.