Broadcasting Message From ASP.NET Core To Angular Client Using SignalR

Technologies 

SignalR

Recently, .NET team has announced SignalR for ASP.NET Core. So, in this article, I am trying to show how we can use SignalR with ASP.NET Core for an Angular client.

Before we begin, below is my environment setup.

Tools/Technologies Versions How to verify version
Angular CLI 1.4.4 Type ‘ng –version’ in nodejs command prompt
NodeJs 6.10.2 Type ‘node -v’ in nodejs command prompt
NPM 3.10.5 Type ‘npm -v’ in nodejs command prompt
.NET Core SDK 2.0.0 Type ‘dotnet –version’ in command prompt
VS Code 1.17.0 In VS code, go to Help > About.
Angular 4.2.4 Angular CLI takes care of this.
ASP.NET Core 2.0.0 .NET CLI takes care of this.
SignalR 1.0.0-alpha1-final NPM and NuGet takes care of this.

In this article, I am going to cover the scenario, where a client is built using Angular (which can be any JavaScript client). For the server side, I am using ASP.NET Core which will have POST API method. On POST method, I am going to send a message to all active clients using SignalR socket.

SignalR

Building ASP.NET Core application (MessageHub and WebApi)

First, we are going to create an ASP.NET Core web application. For this, open the command prompt and type this command.

  1. dotnet new web  

This will create an empty web application folder. This will be very minimal ASP.NET Core application. Open this project using VS code.

In .csproj file, add signalR alpha release package.

  1. <Project Sdk="Microsoft.NET.Sdk.Web">  
  2.   
  3.   <PropertyGroup>  
  4.     <TargetFramework>netcoreapp2.0</TargetFramework>  
  5.   </PropertyGroup>  
  6.   
  7.   <ItemGroup>  
  8.     <Folder Include="wwwroot\" />  
  9.   </ItemGroup>  
  10.   
  11.   <ItemGroup>  
  12.     <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />  
  13.     <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.0-alpha1-final" />  
  14.   </ItemGroup>  
  15.   
  16. </Project>  

Save the .csproj file and go to command prompt. Type the following command which will add SignalR package into ASP.NET Core application. Sometimes, you need to restart the VS code to get the intelliSense of the newly added package.

  1. dotnet restore  
Now, add SignalR in startup.cs.
  1. public void ConfigureServices(IServiceCollection services)  
  2.         {  
  3.             services.AddSignalR();  
  4.             services.AddMvc();  
  5.         }  

Now, we are going to create Hub (e.g.MessageHub) This is the hub where clients are going to connect to and then receive the broadcast messages.

Create a new file named as MessageHub.cs. In this, we have "Send" method where we are going to pass message and this message will be broadcast to all the clients.

  1. public class MessageHub : Hub  
  2. {  
  3.     public Task Send(string message)  
  4.     {  
  5.         return Clients.All.InvokeAsync("Send", message);  
  6.     }  
  7. }  

Then, configure the ASP.NET Core route to our hub (i.e. MessageHub).

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
  2.         {  
  3.             app.UseSignalR(routes =>  
  4.             {  
  5.                 routes.MapHub<MessageHub>("message");  
  6.             });  
  7.   
  8.             app.UseMvc();  
  9.   
  10.         }  

Now, we will create simple Controller with Post action. For demo purposes, we will call this POST action from postman and this will broadcast a message to all clients.

  1. public class MessageController : Controller   
  2.     {  
  3.         private IHubContext<MessageHub> _messageHubContext;  
  4.   
  5.         public MessageController(IHubContext<MessageHub> messageHubContext)  
  6.         {  
  7.             _messageHubContext = messageHubContext;  
  8.         }  
  9.   
  10.         public IActionResult Post()  
  11.         {  
  12.             //Broadcast message to client  
  13.             _messageHubContext.Clients.All.InvokeAsync("send""Hello from the hub server at " +   
  14. DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"));  
  15.    
  16.             return Ok();  
  17.         }  
  18.     }  

Since we are building a separate Angular client app which will be running on the separate port, we need to enable CORS in startup.

  1. public class Startup  
  2.     {  
  3.         // This method gets called by the runtime. Use this method to add services to the container.  
  4.         // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940  
  5.         public void ConfigureServices(IServiceCollection services)  
  6.         {  
  7.             services.AddSignalR();  
  8.             services.AddCors(options => options.AddPolicy("AllowAny", x=> {  
  9.                     x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin();  
  10.                 }));  
  11.             services.AddMvc();  
  12.         }  
  13.   
  14.         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
  15.         public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
  16.         {  
  17.             app.UseCors("AllowAny");  
  18.   
  19.             app.UseSignalR(routes =>  
  20.             {  
  21.                 routes.MapHub<MessageHub>("message");  
  22.             });  
  23.   
  24.             app.UseMvc();  
  25.   
  26.         }  
  27.     }  

Building Angular Client App

Now, let’s create Angular client app using angular CLI. To create a simple angular application type ng new <PROJECT-NAME> in node.js command prompt window. This will create a basic Angular app. Once the project is created successfully, type npm install to install the dependencies.

To use, signalR on client, we need to install the signalr-client npm module first using the following command: 

  1. npm install @aspnet/signalr-client –save  

After successful installation, your package.json looks like this-

  1. {  
  2.   "name""signal-r-angular4",  
  3.   "version""0.0.0",  
  4.   "license""MIT",  
  5.   "scripts": {  
  6.     "ng""ng",  
  7.     "start""ng serve",  
  8.     "build""ng build",  
  9.     "test""ng test",  
  10.     "lint""ng lint",  
  11.     "e2e""ng e2e"  
  12.   },  
  13.   "private"true,  
  14.   "dependencies": {  
  15.     "@angular/animations""^4.2.4",  
  16.     "@angular/common""^4.2.4",  
  17.     "@angular/compiler""^4.2.4",  
  18.     "@angular/core""^4.2.4",  
  19.     "@angular/forms""^4.2.4",  
  20.     "@angular/http""^4.2.4",  
  21.     "@angular/platform-browser""^4.2.4",  
  22.     "@angular/platform-browser-dynamic""^4.2.4",  
  23.     "@angular/router""^4.2.4",  
  24.     "@aspnet/signalr-client""^1.0.0-alpha1-final",  
  25.     "core-js""^2.4.1",  
  26.     "rxjs""^5.4.2",  
  27.     "zone.js""^0.8.14"  
  28.   },  
  29.   "devDependencies": {  
  30.     "@angular/cli""1.4.4",  
  31.     "@angular/compiler-cli""^4.2.4",  
  32.     "@angular/language-service""^4.2.4",  
  33.     "@types/jasmine""~2.5.53",  
  34.     "@types/jasminewd2""~2.0.2",  
  35.     "@types/node""~6.0.60",  
  36.     "codelyzer""~3.2.0",  
  37.     "jasmine-core""~2.6.2",  
  38.     "jasmine-spec-reporter""~4.1.0",  
  39.     "karma""~1.7.0",  
  40.     "karma-chrome-launcher""~2.1.1",  
  41.     "karma-cli""~1.0.1",  
  42.     "karma-coverage-istanbul-reporter""^1.2.1",  
  43.     "karma-jasmine""~1.1.0",  
  44.     "karma-jasmine-html-reporter""^0.2.2",  
  45.     "protractor""~5.1.2",  
  46.     "ts-node""~3.2.0",  
  47.     "tslint""~5.7.0",  
  48.     "typescript""~2.3.3"  
  49.   }  
  50. }  

Then, open the Angular app in VS code and let’s try to consume signalR. In this we are trying to do couple of things-

  1. We will try to connect HubConnection and on successful connection, we will write a console log saying MessageHub Connected.
  2. On Every message received from client, we are going to display that message in the client’s console.

    In Angular client app, open the app.component.ts file and add the below code in it.
    1. import { Component, OnInit } from '@angular/core';  
    2. import { HubConnection } from '@aspnet/signalr-client';  
    3.   
    4. @Component({  
    5.   selector: 'app-root',  
    6.   templateUrl: './app.component.html',  
    7.   styleUrls: ['./app.component.css']  
    8. })  
    9. export class AppComponent implements OnInit {  
    10.   title = 'app';  
    11.   
    12.   ngOnInit() : void {  
    13.   
    14.     let connection = new HubConnection('http://localhost:5000/message');  
    15.       
    16.     connection.on('send', data => {  
    17.         console.log(data);  
    18.     });  
    19.       
    20.     connection.start()  
    21.     .then(() => {  
    22.       console.log('MessageHub Connected');  
    23.     });  
    24.   
    25.   }  
    26. }  

Test our sample

As both our applications are ready, it is time to take the functionality. To test, we are going to follow the below steps-

  1. In command prompt, type dotnet run to run our ASP.NET Core application.
  2. In node.js command prompt, type ng serve to run our Angular application.
  3. Open browser and its console and type http://localhost:4200
  4. Open Postman app, send POST request to http://localhost:5000/api/message
  5. You will get the result status 200 OK in postman
  6. On browser console, you will see a message as “Hello from the hub server at 08-10-2017 00:41:12”.

In my testing, I have used 3 different browsers (as 3 different clients) and all 3 have received a message from hub. Below are the screenshots of my tests.

SignalR
Screenshot1: Postman showing Status 200 OK.

SignalR
Screenshot2: Chrome browser showing console messages

SignalR
Screenshot 3: Edge browser showing console messages

SignalR
Screenshot 4: Opera browser showing console messages

References