In this article, we will see how we can create real time clock, using SignalR, Angular 2 and integrate Angular 2 app inside ASP.NET in addition to viewing its results.
Before proceeding to the step by step process of creating a real time clock, it’s better to understand a few important terms and concepts.
What is the meaning of real time communication?
Real time communication (RTC) is a term, which means a communication which does not have delays, as the clients connect to each other through the Server when any client sends a message as soon as the Server receives it it pushes it towards another connected or all the connected clients without any delay. Like Instant Messaging Services, we use popular Services like WhatsApp, IMO and Facebook Messenger.
It uses peer-to-peer connection with minimum latency, RTC data and messages are not stored between the transmissions.
I think, it’s enough to have information on real time communication, if you are willing to deep dive, you can check out the available content on the Web.
Now, we will discuss it.
What is ASP.NET SignalR?
It is an ASP.NET library which adds real time functionality to the Web apps. As we already discussed, in real time communication, the Server receives the data without storing it and pushes it towards the connected clients.
SignalR provides a simple API for generating Server to client Remote Procedure Calls (RPC) that hits with JavaScript functions on the client from the Server side or the same. It is reciprocal from the client to the Server, as it supports bi-directional communication.
SignalR contains built in rich mechanisms for the management of connections, and methods to connect, disconnect or reconnect are available to override, grouping, and authorization.
And the last but not the least technology, which we use to create an app, is Angular 2.
What is Angular 2?
Angular 2 is a rich UI Framework to build mobile and Web applications. It is built using JavaScript. It has many enhancements over its first version, Angular 1. It is recreated and now it is better to develop applications with Angular 2, as it has an extended set of features mentioned below.
- Cross Browser and Cross Platform compatibility.
- Two way data binding.
- Enhanced routing support.
- Modular structure to manage your code.
- Excellent community support.
- High speed and performance
- Fully productive tools to fast pace your work
- Unit testing
This is a brief introduction of all the things we can create with the web app.
So let’s start to build the app step by step.
Step 1
Go to File - New - Project and select ASP.NET Web Application. Afterwards, name the project and the destination. Press OK.
After pressing OK Button it will open new window to select the template of the new project.
In our case, we are using an empty template with MVC check box checked.
Now, press OK button again to create the project.
We have successfully created our Web Application.
Step 2
Now, we will first install SignalR to the created app.
For this, we would right click the project and select Manage NuGet Packages.
NuGet Package Manager Window opens, search SignalR, press Install button to install the packages.
Now, review the changes. A window opens and these changes are reflected on your solution after installing it.
Press OK button to continue.
After this License Acceptance Window opens, click I accept to accept the license, otherwise press I Decline.
As this is the final step towards installing SignalR through NuGet Package Manger and it can install all the dependencies and the Scripts needed for the project. It opens the Project folder in which the change has occurred.
You can verify if the package is installed or not by verifying the tick mark on the package which you installed in the NuGet Package Manager Window.
Step 3
Download and install NodeJS for Windows.
Go to https://nodejs.org/en/ and click on the recommended version to be installed for Windows.
After downloading, install Microsoft installer file and follow the steps to install in your local machine.
To check if it has successfully installed on your local machine, open Command Prompt Window and Type node –v and hit enter. If it returns the node version, as shown in the image, it has been successfully installed.
Also, verify NPM is installed by typing the command npm –v.
Step 4
Add OWIN Startup class to the project by adding New Item to the root of the project.
After the file is created, add the code given below to the file inside Configuration method.
Step 5
Add SignalR Hub Class to the Project. The better approach is to make a folder with the name of hubs and add Hub Class inside it.
We first create the folder, namely Hubs, and create a Hub Class by right clicking on the folder. Select Add è SignalR Hub Class, name it and it will add hub class to the folder.
I have created Hub class with the name of Clock. By default, it will be created with Hello method.
Copy and paste the method given below to follow this tutorial.
- public void GetRealTime() {
- Clients.Caller.setRealTime(DateTime.Now.ToString("h:mm:ss tt"));
- }
Now, let’s elaborate on this method. As you can see GetRealTime is a hub method and it is a Server side method. From client, we hit this Server side event and on the result, it makes a remote procedure call and sends the response back to the client by calling Clients.Caller.setRealTime method, which is then used in the client side to accept the response and show to the client.
Caller means the calling client, which is connected to the hub.
setRealTime function is used in the client end to broadcast and show the response.
Step 6
Now, we will move to setup the Angular 2 environment for your project.
If you want to quick start your project, you can use the ready made available project of Angular2 from official GitHub account of Angular2 and clone the project to do a quick start.
I have enlisted the steps below to setup your local development environment.
- Make sure that you have installed node and NPM. Node is for the client side Applications and build tools and NPM Package Manager installs JavaScript libraries.
- Create Angular 2 folder on the root of your project and then app folder, where we place only Angular2 code and in Angular2 folder, we place the configuration and other files are required at the root.
- Create the Configuration files.
- First, create the tsconfig.json file. For this, press Ctrl + Shift + A or right click Angular 2 folder and select Add New Item from context menu. A new Window appears, select JSON file, name it tsconfig.json and press Add to create the file. The basic purpose of this file is to set the environment for TypeScript compilation configuration. Through this file, all TypeScript files transpiles to Javascript. Add the code given below to the file.
- {
- "compilerOptions": {
- "target": "es5",
- "module": "system",
- "moduleResolution": "node",
- "sourceMap": true,
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "removeComments": false,
- "noImplicitAny": false
- },
- "exclude": ["node_modules", "typings/main", "typings/main.d.ts"]
- }
- Now, create the file through the procedure given above, namely typings.json, which can identity the TypeScript definition’s file in your Angular Application. There are three types of files defined in file. A) core-js b) jasmine and c) node. Copy the code given below to the file.
- {
- "globalDependencies": {
- "core-js": "registry:dt/core-js#0.0.0+20160602141332",
- "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
- "node": "registry:dt/node#6.0.0+20160621231320"
- }
- }
- Now, create package.json file. This file contains the packages required by our app. The packages are installed and maintained, using Node Package Manager. Copy the code given below to the file.
- {
- "name": "angular2realtimeclock",
- "version": "1.0.0",
- "scripts": {
- "start": "concurrent \"npm run tsc:w\" \"npm run lite\" ",
- "tsc": "tsc",
- "tsc:w": "tsc -w",
- "lite": "lite-server",
- "typings": "typings",
- "postinstall": "typings install"
- },
- "license": "ISC",
- "dependencies": {
- "angular2": "2.0.0-beta.7",
- "systemjs": "0.19.22",
- "es6-promise": "^3.0.2",
- "es6-shim": "^0.33.3",
- "reflect-metadata": "0.1.2",
- "rxjs": "5.0.0-beta.2",
- "zone.js": "0.5.15"
- },
- "devDependencies": {
- "concurrently": "^2.0.0",
- "lite-server": "^2.1.0",
- "typescript": "^1.7.5",
- "typings": "^0.6.8"
- }
- }
- After creating the files, now open Angular 2 folder in Window Explorer and press Shift + Right Key combination and select “Open Command Window here” option or alternatively point to this folder, using command and write NPM install and press Enter.
After packages are installed, it will create the node_modules and typings folder inside your folder, where you have installed it.
- After the packages have been successfully installed, now, we will create the directory structure for placing the source code of Angular 2. In Angular 2, everything is made up of components, so we will make basic and generic folder structure sites, which consist of Components, Classes, Services, Modules, Routing, Common and Shared folders, so create all of them on the project. It’s not necessary to create all the folders. Start it, as per your requirement, and then extend the functionality by creating the folders, as per your need.
- We will start first of all by creating the base component inside an app folder and their template as well. Create new TypeScript file with the name of app.component.ts in the root of app folder.
Inside the file, first import the component from Angular Core.
- import {Component} from '@angular/core'
Now, create @component decorator and add selector. In this selector, we bind our component to and then template for simple HTML inside file or to use the external template; attach a template via templateUrl, as shown below.
- @Component({
- selector: 'my-app',
- templateUrl: './app/app.component.html'
- })
Lastly, export the class to be usable in other classes to import.
- export class AppComponent { }
- Now, we will create the template of the app component with the name of app.component.html and put the code given below inside it.
- <div id="wrapper">
- <router-outlet></router-outlet>
- </div>
Basically, router-outlet acts as a placeholder for the component that depends on the current router state.
- Now, create app.module, which acts as a base for all the modules which are used and where you can export the component class, values and functions to be used in other modules. Copy and paste the code in the app.module file.
- import {
- NgModule
- } from '@angular/core';
- import {
- BrowserModule
- } from '@angular/platform-browser';
- import {
- AppComponent
- } from './app.component';
- import {
- routing
- } from './app.routes';
- import {
- HttpModule,
- JsonpModule
- } from '@angular/http';
- import {
- ClockComponent
- } from './components/clock/clock.component';
- import {
- SignalRService
- } from './services/signalRService';
- import {
- FormsModule
- } from '@angular/forms';
- @NgModule({
- imports: [
- BrowserModule,
- routing,
- HttpModule,
- JsonpModule,
- FormsModule
- ],
- declarations: [
- AppComponent,
- ClockComponent
- ],
- providers: [
- SignalRService
- ],
- bootstrap: [AppComponent]
- })
- export class AppModule {}
- Now, we will create the main.ts file in the root of Angular app folder, which can bootstrap the app module. Paste the code given below.
- import {
- platformBrowserDynamic
- } from '@angular/platform-browser-dynamic';
- import {
- AppModule
- } from './app.module';
- platformBrowserDynamic().bootstrapModule(AppModule);
- Move to the other step in which we can create the systemjs .config.js file, which can map the app folder files( transpile files to js) of your app, load the packages from the certain path, set the configuration and finally we place on the main entry point of our app page , which is mainly index.html.
- Finally, we will create the index.html file, which is the main entry point of the app, where we register the files like shim, reflect, zone, system js files and also import the files generated previously to the main entry point, using statement System.import (‘path of your mapped app folder’). Inside index.html, place the line of code given below.
- <html>
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="stylesheet" href="styles.css">
- <link href="app/app.component.css" rel="stylesheet" />
- <!-- 1. Load libraries -->
- <!-- Polyfill(s) for older browsers -->
- <script src="node_modules/core-js/client/shim.min.js"></script>
- <script src="node_modules/zone.js/dist/zone.js"></script>
- <script src="node_modules/reflect-metadata/Reflect.js"></script>
- <script src="node_modules/systemjs/dist/system.src.js"></script>
- <!-- 2. Configure SystemJS -->
- <script src="systemjs.config.js"></script>
- <title>Angular 2 Realtime Clock</title>
- <script src="../Scripts/jquery-1.10.2.min.js"></script>
- <script src="../Scripts/jquery.signalR.js" type="text/javascript"></script>
- <script>
- System.import('app');
- </script>
- </head>
- <!-- 3. Display the application -->
-
- <body>
- <!-- headers -->
- <!-- body -->
- <my-app>Loading the app...</my-app>
- <!-- footers-->
- </body>
-
- </html>
In our case, also attach the SignalR and jQuery client files, which are required to fulfill our requirement.
- After finishing the basic configuration, we will now create the functionality to create the realtime clock , using SignalR like our component, model and Service.
- First, we will create the model component. Name the component GetClockTime.ts, place them in the Model folder of your app and paste the code given below inside it.
- export class GetClockTime {
- public Time: string;
- constructor(time: string) {
- this.Time = time;
- }
- }
- In this code block, we created exported class, which is reusable in other components, defined a class member and initialized in the constructor.
- Now, we will create some global constant files as the constants are those variables, where the value cannot be changed through the Application execution life cycle. Name the file as app.constants.ts, place in the generic folder and paste the code given below.
- export let CONFIGURATION = {
- baseUrls: {
- server: 'http://localhost:50347/'
- },
- }
- In this file, we have created the exported variable and added the URL of our Server to be used in the SignalR Service. The basic purpose of using these files is that once we have a list of all the constants that are too frequently used they can be changed in one place and not separately in all the files.
- In the next step, we will create SignalR Service, which is the backbone of all the processes.
-
- import {
- Injectable,
- EventEmitter
- } from '@angular/core';
- import {
- CONFIGURATION
- } from '../generic/app.constants';
- import {
- GetClockTime
- } from '../models/getclocktime';
-
- declare
- var $: any;
- @Injectable()
- export class SignalRService {
-
- private proxy: any;
- private proxyName: string = 'clock';
- private connection: any;
-
- public messageReceived: EventEmitter < GetClockTime > ;
- public connectionEstablished: EventEmitter < Boolean > ;
- public connectionExists: Boolean;
- constructor() {
- debugger;
-
- this.connectionEstablished = new EventEmitter < Boolean > ();
- this.messageReceived = new EventEmitter < GetClockTime > ();
- this.connectionExists = false;
-
- this.connection = $.hubConnection(CONFIGURATION.baseUrls.server);
-
- this.proxy = this.connection.createHubProxy(this.proxyName);
-
- this.registerOnServerEvents();
-
- this.startConnection();
- }
-
- public sendTime() {
-
- this.proxy.invoke('GetRealTime');
- }
-
- private startConnection(): void {
- this.connection.start().done((data: any) => {
- console.log('Now connected ' + data.transport.name + ', connection ID= ' + data.id);
- this.connectionEstablished.emit(true);
- this.connectionExists = true;
- }).fail((error: any) => {
- console.log('Could not connect ' + error);
- this.connectionEstablished.emit(false);
- });
- }
- private registerOnServerEvents(): void {
- debugger;
- this.proxy.on('setRealTime', (data: GetClockTime) => {
- console.log('received in SignalRService: ' + JSON.stringify(data));
- this.messageReceived.emit(data);
- });
- }
- }
Create the Service in the Service folder and paste the code given below inside it.
I have commented each section for ease.
- Further we will create the main component of the realtime clock. Create the new component by first creating the folder of the module then creating component file, namely clock.component.ts.
Place the line of code given below inside it.
- import {
- Component,
- NgZone
- } from '@angular/core';
- import {
- SignalRService
- } from '../../services/signalRService';
- import {
- GetClockTime
- } from '../../models/getclocktime';
-
- @Component({
- selector: 'clock-component',
- templateUrl: './app/components/clock/clock.component.html'
- })
- export class ClockComponent {
-
- public currentMessage: GetClockTime;
- public allMessages: GetClockTime;
- public canSendMessage: Boolean;
-
- constructor(private _signalRService: SignalRService, private _ngZone: NgZone) {
-
- this.subscribeToEvents();
-
- this.canSendMessage = _signalRService.connectionExists;
-
- setInterval(() => {
- this._signalRService.sendTime();
- }, 1000);
- }
- private subscribeToEvents(): void {
-
- this._signalRService.connectionEstablished.subscribe(() => {
- this.canSendMessage = true;
- });
-
- this._signalRService.messageReceived.subscribe((message: GetClockTime) => {
- debugger;
- this._ngZone.run(() => {
- this.allMessages = message;
- });
- });
- }
- }
- Last but not least, we will create a view template against the component, in which we will place the clock to be shown in the Browser. Create the clock.component.html file as a view to show the data to the Browser.
- <style type="text/css">
- p {
- color: #000;
- font-size: 8.7em;
- font-family: Helvetica, Arial;
- padding-top: 0%;
- margin-left: 25%;
- }
- </style>
- <div id="timediv">
- <p>{{allMessages}}</p>
- </div>
Step 6
Launch the project on the Browser by using command prompt NPM start statement or launch the Browser by using Visual Studio F5 and typing Angular 2 to point to Angular 2 app.
Finally, the output is given, as shown below.