How to write real-time web app using SignalR, TypeScript, AngularJS, HTML5?

Nowadays, end-users like responsive applications and there are times when certain type of applications need to support real-time updates if required. In this post, I’ll tell you how to write real-time web app using SignalR, TypeScript, AngularJS, HTML5.

I recently published a similar post that explains how to write real-time web app using SignalR, TypeScript, KnockoutJS & HTML5. Most of the concept is same in both the posts but one uses KnockoutJS and AngularJS.

As such this is a how-to post, I expect readers to have some basic knowledge about these technologies mentioned above. But in a nutshell:

What is SignalR?

ASP.NET SignalR is a new library for ASP.NET developers that makes developing real-time web functionality easy. SignalR allows bi-directional communication between server and client. Servers can now push content to connected clients instantly as it becomes available. SignalR supports Web Sockets, and falls back to other compatible techniques for older browsers. SignalR includes APIs for connection management (for instance, connect and disconnect events), grouping connections, and authorization.
ASP.NET

What is TypeScript?

Typescript is a typed superset of JavaScript that compiles to plain JavaScript. It runs in any browser, any host and any OS. It is open source with good tooling support for various IDE and code editors.
– Learn more about it here.

What is AngularJS?

AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML’s syntax to express your application’s components clearly and succinctly. Angular’s data binding and dependency injection eliminate much of the code you would otherwise have to write. And it all happens within the browser, making it an ideal partner with any server technology.
AngularJS

Requirement/Scope

A real-time web application can be really exciting and SignalR makes it more interesting by providing strong client support as it can leverage Web Sockets, Server-Sent Events (SSE), Forever Frame and Long Polling whenever needed.

Let us define the scope of the real-time application that will be ready by the end of this post. There is a requirement to show the CPU, paging and disk usage on the server to the users of our web application. This can be part of an internet or intranet web app. The code snippets in this post doesn’t account authentication or authorization to keep the scope simple. Ideally, this kind of information can be a part of app’s dashboard.

Tools/Packages

I’m using Visual Studio for this requirement to create an ASP.NET web application with MVC & Web API and name it as  “PerfSurf”. I opted this template type so as to get Bootstrap, jQuery and some other default packages. Make sure you have proper TypeScript support in your IDE with latest Web Essentials update.

Use the Nuget Package Manager to install following packages: AngularJS, SignalR and their nuget packages names are “angularjs”, “Microsoft.AspNet.SignalR” respectively.

To show the real-time updates on the user-interface get Smoothie.js, a charting library. Unfortunately, this is not available via nuget at the time of writing this post. So, visit the link, copy the raw library code and paste it in a new file in your vendor specific scripts folder.

To leverage strong typing support of TypeScript, install following packages: jquery.TypeScript.DefinitelyTyped, angularjs.TypeScript.DefinitelyTyped, signalr.TypeScript.DefinitelyTyped, smoothie.TypeScript.DefinitelyTyped. These are the definition files that helps an IDE to give proper intellisense support.

Server-side Setup

Based on your authentication type – Internet or Intranet, you may or may not have a Startup.cs file in your project at root level. If it is not there, add this file and configure the app to use SignalR. My project is internet type so I already had this file and it looks like this:

The method named MapSignalR maps SignalR hubs to the app builder pipeline at /signalr.

Hub

The next main step is to create a custom Hub that derives from Microsoft.AspNet.SignalR.Hub. It provides methods that communicate with SignalR connections that is connected to a hub. This hub will basically define all the methods (marked public) that clients (browser) can use. Below is the code to create a hub for our requirement:

The code statement Clients.All.NewCounters(results); instructs SignalR to invoke a JavaScript function named newCounters() on every connected client and pass results object as parameter to it. The All member is a dynamic object which allow us to add any name. In the later version of SignalR, a new feature was added which allows a custom Hub to inherit from the base hub of specific type where all the members defined in this type is supposed to be implemented in JavaScript/client code.

So, defining a IPerfHubClient interface also provides us intellisense support in IDE otherwise there will be no support as All is a dynamic type. It’s definition is shown below:

HubMethodName attribute on member instructs SignalR to convert pascal-case to camel-case when it creates the client-side methods on the fly for consumption. This is handy as writing a method name in camel-case on server-side doesn’t look right!

Let us look at StartCounterCollection implementation. We want our hub to start sending the counter values as soon as possible. So, we just start a new task which runs a while loop but with some delay. It consumes a custom counter service named PerfCounterService to get the results of CPU, Paging and Disk usage of server which is then sent to all the connected client using Clients.All.NewCounters(results). Note that we also instruct that this task is a long-running task with the help of TaskCreationOptions.

PerfCounterService is a simple class that just setups the counters that the client needs as per the requirement of our application. It is good to keep this separate so that this counters can be added or removed as and when required without affecting the rest of the application. The definition of this class is as follows:

It stores a list of counters to be used in app and GetResults method just returns a friendly name and a value for counter. It uses a custom counter wrapper type  – the definition is mentioned below:

The above class is a wrapper for System.Diagnostics.PerformanceCounter to define a friendly name, category, counter, instance for a counter. Note that all counter have different values for category, counter or instance. Look at the PerfCounterService to check what is required for different required counters.

Client-side Setup

As such this project is using ASP.NET MVC, we will next modify the Home/Index.cshtml view to have following code:

Code from line no. 19-23 reference all the third-party libraries and no. 25-28 reference our app specific code. Line 6-13 uses a script of type template so as to keep the home view close to master view. The id/reference is used by angular to glue up controller and view that is defined in the routing configuration (check code snippet below).

Code from line 7-12 uses Angular’s data-ng-repeat binding to render the structure for all the counters defined in the model. We have 3 counters as per requirement. It then creates a canvas element for each counter with a unique id using counter’s name. This makes sure that our app is ready to support any number of counters sent from the server. Also this canvas is required to use Smoothie chart library so that it can stream data on it.

Next important step is to define an angular module in app.module.ts and the definition is mentioned below. It also defines a route which addresses the template in the code above and a controller.

The definition for home controller is below. I also have a post that describes how to write AngularJS controller using TypeScript in more detail.

It is quite a simple class with counters member as an array that will hold all the counter values. As discussed above, the friendly name of every counter is used to identify whether the counter already exists or not. If it doesn’t exist then a new chart-entry is created and added to the counters array. And eventually, the value is added to the entry irrespective of whether entry is new or old. This also asks angular to inject SignalRService that does all the work to use signalR properly.

The code that uses $on event hook will be explained later in the post.

ChartEntry.ts file is created to define a ChartEntry class internally uses SmoothieChart which defines a chart for a counter. SmoothieChart has a timeSeries which it uses to track a value at particular time. Instead of matching server & client time, we just use client-side time to append a counter’s value. The implementation of this type looks like this below:

The important bit is still remaining to glue SignalR work done on server with client-side setup. Add signal.service.ts file that looks like snippet below:

This service is responsible to connect to /signalr route to make a hub connection and a hub proxy named perfHub. The logging is also enabled at connection and proxy level. The connection is then started.

The event method is used via $emit  method to publish an event whenever server pushes a newCounters message for client. The listeners can then listen to this event and handle it appropriately. In this app, home controller is listening for this event which is defined in its constructor. Internally it calls the addCounters method to update the chart with new value. Using this event concept is useful as this makes service and controller loosely coupled to react for any messages sent from the server.

If you have followed all the instructions in this post, you will now have a working real-time web application which will look like this:

Real-time web app showing Process, Paging and Disk of a server: write real-time web app using SignalR, TypeScript, AngularJS, HTML5

Real-time web app showing Process, Paging and Disk usage of a server.

This will work well on IIS Express on your local machine but make sure to enable Web Sockets for IIS if you are using IIS 8 and above as by default it is turned off.

This sums up this post to write real-time web app using SignalR, TypeScript, AngularJS, HTML5. If you face any issues, let me know and I’ll try to help you. This just scratches the surface and there are many other great real-time usages that can be achieved using SignalR.

Siddharth Pandey

Siddharth Pandey is a Software Engineer with thorough hands-on commercial experience & exposure to building enterprise applications using Agile methodologies. Siddharth specializes in building, managing on-premise, cloud based real-time standard, single page web applications (SPAs). He has successfully delivered applications in health-care, finance, insurance, e-commerce sectors for major brands in the UK. Other than programming, he also has experience of managing teams, trainer, actively contributing to the IT community by sharing his knowledge using Stack Overflow, personal website & video tutorials.

You may also like...

Advertisment ad adsense adlogger