In this article, we will discuss the working of SignalR and its implementation step-by-step.

Agenda

Prerequisites:

Introduction

Benefits of using SignalR

Implementation of SignalR using .NET Core 6 Web API and Angular 14

Step 1

Create a .NET Core Web API application.

Step 2

Configure your project.

Step 3

Provide some additional information about your project.

Step 4

Install SignalR NuGet package.

Step 5

Project Structure:

Step 6

Create IMessageHubClient.cs class inside the Hub Folder.

namespace SignalRDemo.Hub {
    public interface IMessageHubClient {
        Task SendOffersToUser(List < string > message);
    }
}

Step 7

Next, create MessageHub.cs class.

using Microsoft.AspNetCore.SignalR;
namespace SignalRDemo.Hub {
    public class MessageHub: Hub < IMessageHubClient > {
        public async Task SendOffersToUser(List < string > message) {
            await Clients.All.SendOffersToUser(message);
        }
    }
}

Step 8

Later on, create ProductOfferController.cs.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using SignalRDemo.Hub;
namespace SignalRDemo.Controllers {
    [Route("api/[controller]")]
    [ApiController]
    public class ProductOfferController: ControllerBase {
        private IHubContext < MessageHub, IMessageHubClient > messageHub;
        public ProductOfferController(IHubContext < MessageHub, IMessageHubClient > _messageHub) {
                messageHub = _messageHub;
            }
            [HttpPost]
            [Route("productoffers")]
        public string Get() {
            List < string > offers = new List < string > ();
            offers.Add("20% Off on IPhone 12");
            offers.Add("15% Off on HP Pavillion");
            offers.Add("25% Off on Samsung Smart TV");
            messageHub.Clients.All.SendOffersToUser(offers);
            return "Offers sent successfully to all users!";
        }
    }
}

Here we inject IHubContext, which is part of SignalR and provides the functionality to send messages.

Step 9

Next, register a few services related to SignalR and CORS policy in the Program.cs class.

using SignalRDemo.Hub;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddSignalR();
builder.Services.AddCors(options => {
    options.AddPolicy("CORSPolicy", builder => builder.AllowAnyMethod().AllowAnyHeader().AllowCredentials().SetIsOriginAllowed((hosts) => true));
});
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseCors("CORSPolicy");
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
    endpoints.MapControllers();
    endpoints.MapHub < MessageHub > ("/offers");
});
app.UseHttpsRedirection();
app.MapControllers();
app.Run();

Step 10

Finally, run your application. You should see the swagger UI and our API endpoints, which you can use to send messages.

This is all about the backend application. Let’s start with the client application using Angular 14.

Client Application

Step 1

Create Angular application:

ng new SignalRClient

Step 2

Install SignalR library for client application:

npm install @microsoft/signalr --save

Step 3

Install bootstrap for a better user experience:

ng add @ng-bootstrap/ng-bootstrap

Next, add the bootstrap script inside the angular.json file inside the scripts and styles section.

"styles": [
             "src/styles.css",
             "./node_modules/bootstrap/dist/css/bootstrap.min.css"
           ],
           "scripts": [
             "./node_modules/bootstrap/dist/js/bootstrap.min.js"
           ]

Step 4

Next, open the app.component.ts file and add the following code:

import { Component } from '@angular/core';
import { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'SignalRClient';
    private hubConnectionBuilder!: HubConnection;
    offers: any[] = [];
    constructor() {}
    ngOnInit(): void {
        this.hubConnectionBuilder = new HubConnectionBuilder().withUrl('https://localhost:7219/offers').configureLogging(LogLevel.Information).build();
        this.hubConnectionBuilder.start().then(() => console.log('Connection started.......!')).catch(err => console.log('Error while connect with server'));
        this.hubConnectionBuilder.on('SendOffersToUser', (result: any) => {
            this.offers.push(result);
        });
    }
}

Step 5

Later on, add the following Html snippet inside app.component.html to see the product offers that are sent by the server. Here we tested with only one user. In a real-time scenario, there may be many clients who are using the same server. The server will be able to send multiple messages to all the clients.

<h2>Data loaded from the Web API:</h2>
<div *ngIf="offers.length>0" class="alert alert-warning" role="alert">
    <li *ngFor="let item of offers"> 
      Offers: {{item}}
    </li> 
</div>

Step 6

Run your client application:

npm start

Step 7

Open the URL in the browser:

http://localhost:4200/

Here you did not see any offer currently. For that, we need to hit the server API endpoint.

Step 8

Open the swagger UI of our backend application and execute the same as what is shown below:

Step 9

Again, open the client application window. You will see the offer message.

In a real-time scenario, we would use a scheduler, hangfire, or something like that that can run the task after a certain period of time and send offers to all end-users.

Conclusion

In this article, we discussed working with SignalR and the benefits and real-time scenarios in which SignalR plays a very important role. Later on, we discussed its practical implementation using .NET Core 6 Web API and the Angular 14 web application.