Home >Web Front-end >JS Tutorial >Build a Real-time SignalR Dashboard with AngularJS

Build a Real-time SignalR Dashboard with AngularJS

William Shakespeare
William ShakespeareOriginal
2025-02-20 12:45:11816browse

Build a real-time service monitoring panel!

Build a Real-time SignalR Dashboard with AngularJS Our service monitoring panel will display real data in real time. It will show us what is happening on servers and microservices in a nearly real-time, asynchronous, non-blocking way.

Click here to view the full client example.

Watch using D3.js to visualize data and explain your data in JavaScript! Watch this course Watch this course Showcase the server demonstration here.

We will use the AngularJS framework and many cool real-time charts and a lot of real-time data to build a simplified version of this monitoring panel. We will also build our services using the SignalR and Web API library of .NET 4.5.

Key Points

  • Use AngularJS and SignalR to create a real-time monitoring panel that displays server and microservice activity asynchronously and non-blocking.
  • Set up your project with plain text files or Visual Studio, with dependencies including AngularJS, jQuery, Bootstrap, SignalR, and various chart libraries such as D3.js and Epoch.
  • Implement SignalR center on the server side to manage real-time data transmission, leverage .NET's ability to handle asynchronous requests and push notifications to clients.
  • Develop AngularJS services and controllers to process data received from SignalR centers, and update the UI in real time to reflect changes in server performance metrics.
  • Integrate diagram solutions such as ng-epoch and n3-pie to visually represent data, enhancing the interactivity and user engagement of the monitoring panel.

Technical Architecture

Client

AngularJS enforces good application development practices out of the box. Everything is injected, which means the dependencies are low in coupling. Additionally, Angular has good separation between view, model and controller.

Angular adds .NET here, allowing server-side code to be kept compact, manageable and testable. Server-side code is only used to take advantage of its advantages - to carry out heavy processing.

Server side

Using SignalR with .NET 4.5's Web API is very similar to using Node.js with Socket.IO and allows the same type of non-blocking, asynchronous push from the server to the subscription client. SignalR uses WebSockets at the bottom, but because it abstracts communication, when running inside Angular it falls back to any technology supported by the client browser. (For example, for older browsers, it may fall back to long polling.)

In addition, with the magic of dynamic tags and Json.NET, the .NET framework regards JavaScript as a first-class citizen. In fact, using Web API and SignalR technology through JavaScript is usually easier than through native .NET clients because they are built with JavaScript in mind.

Core content

Start Settings

All AngularJS code used in this tutorial can be found here.

I will cover how to create it using your favorite text editor and plain folders as well as Visual Studio, depending on the tool that creates the project.

Set with plain text files

Folder and file structure are as follows:

<code>root
    app     (Angular应用程序特定的JavaScript)
    Content (CSS等)
    Scripts (引用的JavaScript等)
    ...
    index.html</code>

Main dependencies

You need to download the following file:

  • jQuery (select the link "Download compressed production jQuery 2.1.1")
  • AngularJS (click on the large "Download" option and click the latest version of Angular 1.3)
  • Bootstrap (click the "Download Bootstrap" option)
  • SignalR (click the "Download ZIP" button on the right)
  • D3.js (click the "d3.zip" link in the middle of the page)
  • Epoch (click "Download v0.6.0 link")
  • ng-epoch (click the "Download ZIP" button on the right)
  • n3-pie (click the "Download ZIP" button on the right)

In our Scripts folder, we need:

  • jquery-2.1.1.min.js
  • angular.min.js
  • bootstrap.min.js
  • jquery.signalR.min.js
  • d3.min.js
  • epoch.min.js
  • pie-chart.min.js

In our Content folder:

  • bootstrap.min.css
  • epoch.min.css

Setting with Visual Studio

If you think the text file is too simple, it is very easy to set up through Visual Studio.

Simply set up an empty web application by going to the file -> Create a new -> project and selecting Web as the template type.

Build a Real-time SignalR Dashboard with AngularJS Then just right-click on the project, go to the Manage Nuget package, search and download jQuery, AngularJS, Bootstrap, D3 and SignalR JavaScript clients.

After downloading and installing these, you should see them in the Scripts and Contents folders. Also, under the installed Nuget package, you will see the following:

Build a Real-time SignalR Dashboard with AngularJS Finally, Nuget does not contain Epoch, ng-epoch, and n3 chart libraries, so you need to add them manually. Just follow the steps detailed in the previous section to get these libraries.

Let's write our application

Now we are ready to write some code.

First, let's create our basic index.html file, which will hold our Angular JavaScript code.

<code class="language-html"><!DOCTYPE html>


  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AngularJS - SignalR - ServiceDashboard</title>
  <link rel="stylesheet" href="Content/bootstrap.min.css">
  <link rel="stylesheet" href="Content/epoch.min.css">

  
  
  
  

  
  
  
  

  
  
  
  





</code>

There are some things to pay attention to. First, we added all dependencies so that they load. Second, we reference some new files that do not exist yet (all files in the app folder). We will write these files next.

Let's go to our app folder and create our app.js file. This is a very simple file.

<code>root
    app     (Angular应用程序特定的JavaScript)
    Content (CSS等)
    Scripts (引用的JavaScript等)
    ...
    index.html</code>

This file does a few things for us. It sets up our main application module angularServiceDashboard and injects two external references - ng.epoch (which is our Epoch.js Angular directive) and n3-pie-chart (which is a structure made for Angular Good chart library).

If you noticed, we also injected a value into the backendServerUrl, which is of course hosted elsewhere, and we plan to use it here.

Let's create a service factory class that will bind to the server's URL. This will be the services.js file referenced in our HTML, which will go to the app folder:

<code class="language-html"><!DOCTYPE html>


  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AngularJS - SignalR - ServiceDashboard</title>
  <link rel="stylesheet" href="Content/bootstrap.min.css">
  <link rel="stylesheet" href="Content/epoch.min.css">

  
  
  
  

  
  
  
  

  
  
  
  





</code>

This code uses the popular on and off (no need for off here) subscription mode and encapsulates all communication with SignalR of our application by using the Angular factory.

This code may look a little overwhelming at first glance, but you will understand it better when we build the controller. All it does is get the URL and SignalR center name of the backend SignalR server. (In SignalR, you can use multiple hubs in the same server to push data.)

In addition, this code allows the SignalR server (located in some box elsewhere) to call our application via the on method. It allows our application to call functions inside the SignalR server through the invoke method.

Next, we need our controller, which will bind our data from the service to our scope. Let's create a file named controllers.js in our app folder.

<code class="language-javascript">'use strict';

var app = angular.module('angularServiceDashboard', ['ng.epoch','n3-pie-chart']);
app.value('backendServerUrl', 'http://sitepointsignal.cloudapp.net/');</code>

This controller does something here. It creates our Angular service object and binds it to a callback function so that the server calls something in our controller.

You will see that every time the server calls back us, we will iterate over the JSON array returned by the server. Then we have a switch statement for each performance type. Now we will set the RAM and then go back and fill the rest.

As for our instructions, we actually only need one Epoch chart for us. We will use an open source directive called ng-epoch.js which we have referenced in our index.html stub file.

We can split all these charts into different instructions, use some templates and use UI-Router, but for the sake of simplicity of this tutorial, we will put all the views in our index.html file.

Now let's add our view to the index.html file. We can do this by adding the following content under the body tag:

<code class="language-javascript">'use strict';

app.factory('backendHubProxy', ['$rootScope', 'backendServerUrl', 
  function ($rootScope, backendServerUrl) {

    function backendFactory(serverUrl, hubName) {
      var connection = $.hubConnection(backendServerUrl);
      var proxy = connection.createHubProxy(hubName);

      connection.start().done(function () { });

      return {
        on: function (eventName, callback) {
              proxy.on(eventName, function (result) {
                $rootScope.$apply(function () {
                  if (callback) {
                    callback(result);
                  }
                 });
               });
             },
        invoke: function (methodName, callback) {
                  proxy.invoke(methodName)
                  .done(function (result) {
                    $rootScope.$apply(function () {
                      if (callback) {
                        callback(result);
                      }
                    });
                  });
                }
      };
    };

    return backendFactory;
}]);</code>

This will simply create a location that allows the server to push the RAM data back. The data will first enter our service, then enter the controller, and finally enter the view.

It should look like this:

Build a Real-time SignalR Dashboard with AngularJS Now let's add some charts, which is exactly what we really want to do. We will add a variable named timestamp to the epoch.js timeline. We will also add an array called chartEntry which we will bind to our epoch.ng directive.

<code>root
    app     (Angular应用程序特定的JavaScript)
    Content (CSS等)
    Scripts (引用的JavaScript等)
    ...
    index.html</code>

Then let's map the data in the switch statement and add the remaining required epoch.js data items. Of course, we can break it down further (for example, using more functions and filters), but for the sake of simplicity of this tutorial, we will keep it simple.

<code class="language-html"><!DOCTYPE html>


  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AngularJS - SignalR - ServiceDashboard</title>
  <link rel="stylesheet" href="Content/bootstrap.min.css">
  <link rel="stylesheet" href="Content/epoch.min.css">

  
  
  
  

  
  
  
  

  
  
  
  





</code>

Our controller looks more complete. We have added a realtimeAreaFeed to the scope, which we will bind to our view through the ng-epoch directive, and we have also added areaAxes in the scope, which determines the layout of the area graph.

Now let's add the directive to index.html and display the incoming CPU value data:

<code class="language-javascript">'use strict';

var app = angular.module('angularServiceDashboard', ['ng.epoch','n3-pie-chart']);
app.value('backendServerUrl', 'http://sitepointsignal.cloudapp.net/');</code>

chart-class refers to the color scheme of D3.js, chart-height is what you guessed, chart-stream is the data returned from the SignalR server.

With it, we should see the chart appear in real time:

Build a Real-time SignalR Dashboard with AngularJS Now let's connect a large number of data points to this chart and add another chart from the n3-pie framework (because who doesn't like pie charts!).

To add a pie chart from the n3-pie framework, just add the following to our controller:

<code class="language-javascript">'use strict';

app.factory('backendHubProxy', ['$rootScope', 'backendServerUrl', 
  function ($rootScope, backendServerUrl) {

    function backendFactory(serverUrl, hubName) {
      var connection = $.hubConnection(backendServerUrl);
      var proxy = connection.createHubProxy(hubName);

      connection.start().done(function () { });

      return {
        on: function (eventName, callback) {
              proxy.on(eventName, function (result) {
                $rootScope.$apply(function () {
                  if (callback) {
                    callback(result);
                  }
                 });
               });
             },
        invoke: function (methodName, callback) {
                  proxy.invoke(methodName)
                  .done(function (result) {
                    $rootScope.$apply(function () {
                      if (callback) {
                        callback(result);
                      }
                    });
                  });
                }
      };
    };

    return backendFactory;
}]);</code>

Of course, this value will be updated by the SignalR server. You can see this in the complete code of our controller.

We should also take a moment to think about the full code of our view.

We should see the following data on the screen:

Build a Real-time SignalR Dashboard with AngularJS We have seen that Angular can connect to SignalR very easily - just insert an endpoint in an AngularJS service or factory. AngularJS factory is an encapsulation mechanism that communicates with SignalR. After "combining", who knows that AngularJS and .NET will work together so perfectly?

Core aspects of server

I will introduce some .NET code that allows this communication on the backend. (You can find the source code here.)

First, to start building server code, you need to run SignalR in your Visual Studio solution. To do this, just follow the excellent tutorials on ASP.NET to run the basic SignalR solution. (This is the easiest.)

After running, change the C# Hub class to the following:

<code class="language-javascript">'use strict';

app.controller('PerformanceDataController', ['$scope', 'backendHubProxy',
  function ($scope, backendHubProxy) {
    console.log('trying to connect to service')
    var performanceDataHub = backendHubProxy(backendHubProxy.defaultServer, 'performanceHub');
    console.log('connected to service')
    $scope.currentRamNumber = 68;

    performanceDataHub.on('broadcastPerformance', function (data) {
      data.forEach(function (dataItem) {
        switch(dataItem.categoryName) {
          case 'Processor':
            break;
          case 'Memory':
            $scope.currentRamNumber = dataItem.value;
            break;
          case 'Network In':
            break;
          case 'Network Out':
            break;
          case 'Disk Read Bytes/Sec':
            break;
          case 'Disk Write Bytes/Sec':
            break;
          default:
            //default code block
            break;           
        }
      });     
    });
  }
]);</code>

After changing the Hub class, Visual Studio will report an error, you need to add a performance model (due to Json.NET, it will automatically convert to JSON when the server pushes):

<code>root
    app     (Angular应用程序特定的JavaScript)
    Content (CSS等)
    Scripts (引用的JavaScript等)
    ...
    index.html</code>

JsonProperty metadata just tells Json.NET to automatically convert property names to lowercase when converting to JSON for this model. JavaScript likes lowercase.

Let's add a PerformanceEngine class that will push real performance data to any listening client via SignalR. The engine sends these messages to any listening client via SignalR through an asynchronous background thread.

Due to its length, you can find the code in our GitHub repository.

This code basically pushes a series of performance metrics to any subscribed client in each while iteration. These performance metrics are injected into the constructor. The speed of push from the server is set on the constructor parameter pollIntervalMillis.

Note that this will work well if you use OWIN as self-hosting to host SignalR, and it should work well if you use web worker threads.

The last thing to do is of course start the background thread somewhere in the OnStart() or Startup class of the service.

<code class="language-html"><!DOCTYPE html>


  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AngularJS - SignalR - ServiceDashboard</title>
  <link rel="stylesheet" href="Content/bootstrap.min.css">
  <link rel="stylesheet" href="Content/epoch.min.css">

  
  
  
  

  
  
  
  

  
  
  
  





</code>

The two lines of code that start the background thread (as you guessed) are where we instantiate PerformanceEngine and call OnPerformanceMonitor().

Now, I know you might think I'm randomizing data from the server, which is the fact. But to push real metrics, just use the System.Diagnostics library and the PerformanceCounter provided by Windows. I'm trying to keep it simple, but this is what the code looks like:

<code class="language-javascript">'use strict';

var app = angular.module('angularServiceDashboard', ['ng.epoch','n3-pie-chart']);
app.value('backendServerUrl', 'http://sitepointsignal.cloudapp.net/');</code>

Conclusion

We have learned how to use SignalR data through Angular, and we have connected that data to the real-time charting framework on the Angular side.

The demo of the final version of the client is shown here, from which you can get the code.

Build a Real-time SignalR Dashboard with AngularJS The demo of the final version of the server is shown here, and you can get the code from here.

Build a Real-time SignalR Dashboard with AngularJS I hope you enjoy this walkthrough. If you have tried something similar, please let us know in the comments!

FAQ (FAQ) for building a real-time SignalR monitoring panel with AngularJS

How to set SignalR in AngularJS?

Setting up SignalR in AngularJS involves several steps. First, you need to install the SignalR library using NuGet or npm. After installation, you can create a new SignalR center on the server. This center will be responsible for sending and receiving messages. On the client, you need to reference the SignalR JavaScript library and create a connection to your center. You can then start the connection and define the function that handles incoming messages.

How to deal with connection errors in SignalR?

SignalR provides a built-in mechanism for handling connection errors. You can use the .error() function on the central connection to define a callback function that will be called when an error occurs. This callback function can display an error message to the user or try to reconnect to the center.

Can I use SignalR with other JavaScript frameworks?

Yes, SignalR can be used with any JavaScript framework that supports AJAX and WebSockets. This includes popular frameworks such as React, Vue.js, and Angular. You just need to include the SignalR JavaScript library in your project and create a central connection just like you would in any other JavaScript application.

How to use SignalR to send messages from server to client?

To send messages from the server to the client, you can use the Clients property of the center. This property provides a method for sending messages to all connected clients, specific clients, or client groups. You can call these methods from any part of the server code to send real-time updates to your client.

How to protect my SignalR application?

SignalR provides several options to protect applications. You can use the [Authorize] property to restrict access to your center and center methods. You can also specify a custom authorizer for your hub using the MapHubs() method in the Global.asax file. Additionally, you can use SSL to encrypt SignalR traffic and prevent eavesdropping.

How to deal with disconnection in SignalR?

SignalR automatically handles disconnection and attempts to reconnect. However, you can also manually handle disconnection using the .disconnected() function on the central connection. This function allows you to define a callback function that will be called when the connection is lost.

Can I use SignalR on a non.NET server?

SignalR is a .NET library designed to be used with .NET servers. However, SignalR can be used on non-.NET servers by using compatible WebSocket libraries. You need to implement the SignalR protocol on the server and handle the connection and messaging logic yourself.

How to test my SignalR application?

You can test your SignalR application using tools like Postman or Fiddler and send HTTP requests to your center and verify the response. You can also write unit tests for your central methods and client functions.

Can I use SignalR in my mobile app?

Yes, you can use SignalR in your mobile app. The SignalR JavaScript library can be used in hybrid mobile applications built with Cordova or Ionic. For native mobile apps, both iOS and Android provide SignalR clients.

How to extend my SignalR application?

SignalR provides several options to extend the application. You can use Azure SignalR service, a fully managed service that handles all SignalR connections for you. You can also use the backend, which is a software layer for distributing messages between multiple servers.

The above is the detailed content of Build a Real-time SignalR Dashboard with AngularJS. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn