In this article I will be showing you how to use SignalR in Dotnet core with angular.
Question – Is it possible to build a chat application in DotNet ?
Answer – Yes. You need to use SignalR library for it.
What is SignalR?
SignalR is a Dotnet library that enables us to have 2-way communication between client and server.
Usually what happens is a client sends a request to the server. The server returns a response. But what if the server wants to send something to client without the client requesting it. For example a notification.
That is where you can use SignalR. SignalR can be used for multiple purposes. For example, building a chat application or sending a notification to all online users. Let’s start
Create a new project and Add dependencies
Create a new project in Dotnet Core. In this tutorial, I have used Angular template in asp.net core web application.
Dependencies-
1) Add the following NuGet package to your project.
Microsoft.AspNetCore.SignalR
2) Install following npm package in your angular project.
@aspnet/signalr
Update Startup.cs class
Add the following in your ConfigureServices method in Startup.cs class.
services.AddSignalR();
Create another endpoint in the Configure method of your Startup.cs class.
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
//Added
endpoints.MapHub<BroadcastHub>("/chat");
});
Add model for message
Add the following model in your project.
public class MessageModel
{
public int userId { get; set; }
public string message { get; set; }
}
Create the main Hub class for sending messages.
Create the following class in your Dotnet core project and add the method to it. This API is used for 2 way communication. This class inherits from SignalR Hub.
The method broadcasts our message to all users who are online. You can Map the message to a particular user from both the client-side and server-side. In this tutorial, I will show you to do it from client-side. You can learn to do it from the server-side from here.
public class BroadcastHub : Hub
{
public async Task SendMessage(MessageModel message)
{
//This method broadcasts the request received from client to all the connected users
await Clients.Others.SendAsync("NewMessage", message);
}
}
Angular changes
Create the following model inside your angular project. This model will be used to send and receive data from SignalR server API.
export class MessageModel {
constructor(
public userId: number,
public message: string
) { }
}
Create a service for communication.
Create a service inside your angular project. I have named it ConnectionRequestService.
I have defined a subject to emit new values whenever received. You can learn more about subject from here. BaseUrl is the URL of our server API. I have registered several events in the constructor.
1)Creating connection with the hub on the server .
2)Listening for incoming request and emitting new data through subject.
3) Start connection.
I have also defined a SendMessage() method which we will call from our component to send message to our server API.
import { EventEmitter, Inject, Injectable } from '@angular/core';
import { HubConnection } from '@aspnet/signalr/dist/esm/HubConnection';
import { HubConnectionBuilder } from '@aspnet/signalr/dist/esm/HubConnectionBuilder';
import { Subject } from 'rxjs';
import { MessageModel } from '../Models/MessageModel';
@Injectable({
providedIn: 'root'
})
export class ConnectionRequestService {
BaseUrl: string;
MessageSubject = new Subject<MessageModel>();
private Connection: HubConnection;
constructor(@Inject('BASE_URL') baseUrl: string) {
this.BaseUrl = baseUrl;
//create connection
this.Connection = new HubConnectionBuilder()
.withUrl(this.BaseUrl + 'chat')
.build();
//listen for incoming request
this.Connection.on('NewMessage', (data: any) => {
this.MessageSubject.next(data);
});
//start connection
this.Connection.start()
}
sendMessage(Message: MessageModel) {
this.Connection.invoke('SendMessage', Message);
}
}
Create Components
Add sender component
Create two components inside your angular project. A sender component and a receiver component. Add the following HTML code to your sender component.
Here we are creating a two-way binding for Message property of our class. On click of button SendMessage() method of our class will be called.
<input type="text" [(ngModel)] ="Message" />
<button (click)="SendMessage()">Send</button>
Add the following code to your sender component class. Here we have defined SendMessage() method, which calls ConnectionService to send our message to server API.
import { Component, OnInit } from '@angular/core';
import { MessageModel } from '../Models/MessageModel';
import { ConnectionRequestService } from '../service/connection-request.service';
@Component({
selector: 'app-sender-component',
templateUrl: './sender-component.component.html',
styleUrls: ['./sender-component.component.css']
})
export class SenderComponent implements OnInit {
Message: string;
constructor(private ConnectionService: ConnectionRequestService) { }
ngOnInit() {
}
SendMessage() {
this.ConnectionService.sendMessage(new MessageModel(1, this.Message));
}
}
Create receiver component
Add the following HTML code to the receiver component.
<h1>{{ Message }}</h1>
Add the following code to the receiver component class. In the ngOnInit() method we have defined a listener that is listening to any new values emitted by our subject.
You can learn more about the subject from here. After receiving a new value, we are comparing the userid with our current user id. If it matches, we show the message.
Here we are identifying to which user the message belongs to from the client-side. But the same can also be done from the server-side. You can learn it from here.
import { Component, NgZone, OnInit } from '@angular/core';
import { MessageModel } from '../Models/MessageModel';
import { ConnectionRequestService } from '../service/connection-request.service';
@Component({
selector: 'app-receiver-component',
templateUrl: './receiver-component.component.html',
styleUrls: ['./receiver-component.component.css']
})
export class ReceiverComponent implements OnInit {
UniqueUserId: number = 1;
Message: string;
constructor(private ConnectionService: ConnectionRequestService, private _ngZone: NgZone) { }
ngOnInit() {
this.ConnectionService.MessageSubject.subscribe({
next: (request: MessageModel) => {
this._ngZone.run(() => {
if (request.userId == this.UniqueUserId) {
this.Message = request.message;
}
});
}
});
}
}
Update routes
Finally, Define the path in your routing file.
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'SenderComponent', component: SenderComponent },
{ path: 'ReceiverComponent', component: ReceiverComponent },
])
Output :

The code for this tutorial is available on Github at https://github.com/juzer-hakimji/SignalRDemo
Thank you for reading this article. Have a good day.
Share :
Hi,
Hope you liked the post, Thanks for reading 🙂