Skip to content

Build a SignalR Connection Indicator with TypeScript and Knockout

I’ve build a message infrastructure for the company I am working for which allow to collect tons of production data from our factory (about >4’000 db records per minute). In addition I’ve built a web frontend to query this data and to live monitor some of the data. The monitoring includes pushing current server throughput statistic data and event messages like error etc. that that happens in the factory next door including lots of additional data to understand what’s behind these errors.

For this monitoring UI I used TypeScript for most of the Javascript part and SignalR to push the data from the server to the web-client. If no new problems (aka errors, warnings etc.) are shown the question was: “Is SignalR just disconnected or are we at the lucky side of the day and don’t have new problems happening in our old software?”. So I decided to implement a little indicator showing the SignalR connection status. As I googled around a little and mixed/tuned/changed existing solutions I thought it would be nice to write down how I did it for later records.

First lets start up with the tech stack I used: ASP.Net MVC 5 w. Razor, TypeScript 1.6, SignalR 2.2.0, Knockout 3.3 and Bootstrap 3.3.5 are the relevant parts here.

Razor View

I’ve build the following HTML (Razor but doesn’t matter here) view that holds the Bootstrap markup for the four connections states.

<div id="connectionStateContainer" class="hidden">
    <span>Status:</span>
    <span class="label label-info">Connecting</span>
    <span class="label label-success">Connected</span>
    <span class="label label-warning">Reconnecting</span>
    <span class="label label-danger">Disconnected</span>
</div>

As you see I used Bootstrap Labels for visualizing the different connection states. Further more I added data-bind attributes that allow Knockout to bind the visible attribute of the labels to the connectionState observable properties on my view-model. The values $.signalR.connectionState.* are from the SingalR Javascript library. The sourrounding DIV #connectionStateContainer has the Bootstrap class ‘hidden’ so it is initially hidden until the view-model is correctly bound. Otherwise I would see all the label for a short time on screen before there are bound and therefore hidden.

Javascript Code

I have a little piece of plain Javascript code within the page to mainly get the TypeScript generated Javascript library firing.

var liveTickerViewModel = new KaLog.LiveTickerViewModel();
ko.applyBindings(liveTickerViewModel, $("#liveMessageTickerRoot").get(0));
$("#connectionStateContainer").removeClass("hidden");
liveTickerViewModel.startSignalRHub($.connection);

As my TypeScript code does not have any view-code (id’s, selectors, etc.) in it I decided to have those four lines of code within the view/page itself so things are separated. It’s a matter of taste / programming-style.

But anyway: the above code first instantiate my little view-model built with TypeScript (see below) then applies the Knockout databinding’s to that part of the page and remove the hidden class from the surrounding container as now the right label should be ‘visible’. Removing the hidden class will actually result in showing the surrounding DIV container including its content.

Last but not least we tell our view-model to start the SignalR Hub.

TypeScript Code

Now the last part that makes it all work, the TypeScript view-model. Below you see the interesting parts of my view-model or let’s say the connection status indicator related parts of the code.

namespace KaLog {
 export class LiveTickerViewModel {

 /**
 * Represent the SignalR connection state.
 */
 public connectionState: KnockoutObservable<number> = ko.observable(4);

 /**
 * Initialize and start the SignalR hub.
 * @param connection
 * @returns {}
 */
 public startSignalRHub(connection: any) {
 var serverMonitoringHub = connection.serverMonitoringHub;
 ...
 connection.hub.stateChanged((state: SignalRStateChange) => this.connectionStateChanged(state));
 connection.hub.start();
 }

 /**
 * Callback method triggered when the connection state of the SinalR connection changes.
 * @param state
 * @returns {}
 */
 public connectionStateChanged(state: SignalRStateChange): void {
 var stateConversion = { 0: 'connecting', 1: 'connected', 2: 'reconnecting', 4: 'disconnected' };
 console.log('SignalR state changed from: ' + stateConversion[state.oldState] + ' to: ' + stateConversion[state.newState]);

 this.connectionState(state.newState);
 }
 }
}

First we declare our view-model class LiveTickerViewModel. Then we declare and initialize the property connectionState which is a Knockout Observable which holds a value of type number. We initialize it to disconnected.

In the startSingalRHub() method we retrieve the SignalR client hub (generated by the SignalR Javascript Client). On the Hub we attach an event-handler for the stateChanged event which calls the connectionStateChanged() method.

The connectionStateChanged() method does some console output (for debugging purpose) and then set the value of the observable property connectionState to the new SingalR connection state. Setting this value will trigger the databinding from Knockout which result in updating the visible attributes of our Bootstrap labels. Done.

If you don’t need the debug console output you can inline the this.connectionState(state) call straight into the connection.hub.stateChanged-lambda and remove the entire connectionStateChanged-method.

marcd View All

I love to write software. More then two decades ago I managed to make my hobby my full-time job so I spent more then 20 year writing professional software (I guess that makes me a "Senior Software Developer"). The last few years I spend most of the time developing in C#/.Net for all kind of windows-, web- and embedded-software.

In my free time I enjoy my family, taking photos and go diving in cold lakes and rivers in Switzerland.

One thought on “Build a SignalR Connection Indicator with TypeScript and Knockout Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: