Skip to content

SignalR + AngularJS: Info Sources and Insights

November 3, 2013

This article focuses on using AngularJS as the web client UI technology on the receiving end of SignalR data pushes.

For the past few weeks I’ve been engaged in a fascinating in depth exploratory project to learn how to best use SignalR in various situations.  SignalR is Microsoft’s “real time push” framework introduced in 2011.  Version 2.0 was released a couple weeks ago on October 17, 2013.  SignalR provides the capability of server side software being able to push data to clients of all types:  Web Clients running in a browser, and .NET clients like WPF apps, Console Apps, or Windows Services, plus others (see the SignalR web site).  Thus, due to the request/response nature of the HTTP that Web Clients use, for the first time there is an effective and very easy-to-use way for a server to notify Web Clients when something of interest happens on the server.

For example, SignalR makes updating a client UI from the server easy with real time data from:

  • Instrumentation and alarms on machinery, or stock market feeds, or from business intelligence.
  • Real time text notifications to users of things happening they want to know about.  For example, “The Budget Report you ran this morning is now ready.”  Or “There are donuts available in Conference Room 2.”
  • Chat and message board apps.

From working with SignalR for the better part of a month, it is clear to me that this technology will become widely used.  Indeed, at this very moment there are probably thousands of dashboards crying out for SignalR.

Microsoft Info Sources

Read more about the capabilities of SignalR at the Microsoft ASP.NET SignalR website:  http://www.asp.net/signalr.  Especially see “Introduction fo SignalR” for an excellent description — http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/introduction-to-signalr

For detailed info on how to write the code for Web Clients please see this link: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client.

I suggest that you read one of the Tutorials and download its code.  They are typically very simple.

Finally, it was a great help to me to read this link, so as to gain an understanding of Hubs and how to use them:  http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server.

Useful Info Sources for AngularJS Clients of SignalR

In my exploratory app I implemented both a traditional jQuery web client for SignalR, and also an AngularJS SPA (Single Page App) web client.  You will find examples of simple jQuery web clients for SignalR in the ASP.NET SignalR site’s tutorials.

Here are a couple links I found very useful in implementing an AngularJS web client for SignalR:

This link shows a super simple example of an AngularJS client using SignalR:  http://code2thought.blogspot.com/2013/09/doing-signalr-angularjs-way.html

Ingo Rammer and Christian Weyer have a very helpful free ebook devoted to AngularJS and .NET.  One of their chapters is devoted to AngularJS and SignalR:  http://henriquat.re/server-integration/signalr/integrateWithSignalRHubs.html

One key thing to note in the above code is how well the AngularJS service for talking to SignalR separates that concern, from the jobs done by the Controllers that utilize the service.  This creates tight cohesion in both the Controllers and the SignalR service.  And, since AngularJS services are Singletons, this service not only encapsulates behavior, but also encapsulates the state of the service that is shared amongst all the Controllers utilizing the service.  Finally, since Angular services are dependency injected into controllers (via a Service Locator built in to the AngularJS framework), there is loose coupling between the Controller and the service it uses.  This allows for simple mocking and testing of the Controllers, separate from the service.  The above characteristics are common throughout AngularJS since one of the highest priority design goals was to produce very high levels of testability in AngularJS clients.

How to Unregister Event Handlers to Prevent Memory Leaks in AngularJS Controllers

When SignalR pushes a piece of data to a Web Client, the SignalR runtime on the client raises an event saying the data has arrived.  Thus, Web Clients must register subscriptions to these events in order to received the pushed data and process it.

With SPA’s you need to be fanatically concerned with unregistering ALL of the event handlers you register in order to:

  1. Prevent memory leaks, and
  2. Prevent performance degradations over time as more and more not-unregistered event handlers build up with each partial-page-navigation.  Each one responds to its event and does the work it is designed to do even though the element they are registered on is no longer in use.  Thus many CPU cycles are wasted.  This can degrade the performance of an app to a crawl after a number of hours of heavy use.

Non-SPA web clients replace all their JavaScript code on each page-navigation – all the registered event handlers and their references are gone!  No memory leaks, no problem.  So the effects of not unregistering event handlers may seldom be apparent in a non-SPA.

With SPAs, however, the same JavaScript will hang around for multiple navigations to and from the partial pages inherent in SPAs.  Thus, unregistering event handlers on partial page-navigations is an absolute requirement just as it is in Silverlight, WPF, and WinForms apps.  The rule is “If you register an event handler, you must also unregister it before garbage collection of the element it was registered in.  Period.”  And writing the event handler unregistration code at development time is way, way less painful and expensive than trying to chase down memory leaks and performance bottlenecks just before (or even after, gulp) the code has been released into the wild.

Here is the code you can put in an AngularJS Controller that unregisters the event handlers that were registered in the Controller.  This trivial code handles the Angular $destroy event that is raised just before the Controller is garbage collected.

$scope.$on(‘$destory’, function () {

// Here is the place for the code that unregisters each event handler

// that was registered in the Controller, one by one.

};

Note that I have verified this works to unregister handlers for AngularJS events.  But I have NOT yet used it to unregister JavaScript or DOM event handlers.  Caveat emptor!

I hope you find this article helpful.

George Stevens

Creative Commons License

dotnetsilverlightprism blog by George Stevens is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. Based on a work at dotnetsilverlightprism.wordpress.com.

Advertisements
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: