Introduction
Building a real-time chat application is one of the best ways to understand SignalR. SignalR gives you real-time communication using WebSockets or fallbacks, without requiring you to manage low-level socket programming. In this article, we will build a fully working mini chat application using ASP.NET Core for the backend and Angular for the frontend.
This tutorial covers everything required to run a production-ready real-time chat system, including backend setup, Angular integration, authentication basics, and deployment considerations.
High-Level Architecture
The system has three main components:
ASP.NET Core Web API with SignalR Hub
Angular Frontend
Browser Clients
Architecture Diagram
+--------------------+ WebSockets +----------------------+
| Angular Frontend | <------------------------> | ASP.NET Core SignalR |
| Chat Component | | ChatHub + API |
+--------------------+ +----------------------+
| |
| |
+--------------- Real-Time Messages ------------------+
Backend: ASP.NET Core SignalR Setup
Step 1: Create the ASP.NET Core Project
dotnet new webapi -n ChatBackend
cd ChatBackend
Install SignalR package:
dotnet add package Microsoft.AspNetCore.SignalR
Step 2: Create the ChatHub
Create a folder Hubs and add ChatHub.cs.
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace ChatBackend.Hubs
{
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
Step 3: Register SignalR in Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR();
builder.Services.AddCors(options =>
{
options.AddPolicy("corsPolicy", policy =>
{
policy.AllowAnyHeader().AllowAnyMethod().AllowCredentials()
.WithOrigins("http://localhost:4200");
});
});
var app = builder.Build();
app.UseCors("corsPolicy");
app.MapHub<ChatBackend.Hubs.ChatHub>("/chatHub");
app.Run();
The backend is complete.
Frontend: Angular + SignalR
Step 1: Create Angular Project
ng new mini-chat
cd mini-chat
Install SignalR client:
npm install @microsoft/signalr
Step 2: Create Chat Service
File: chat.service.ts
import { Injectable } from '@angular/core';
import * as signalR from '@microsoft/signalr';
import { BehaviorSubject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class ChatService {
private hubConnection!: signalR.HubConnection;
private messageSource = new BehaviorSubject<any>(null);
message$ = this.messageSource.asObservable();
startConnection() {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:5000/chatHub')
.withAutomaticReconnect()
.build();
this.hubConnection
.start()
.catch(err => console.log('Error while starting connection: ' + err));
this.hubConnection.on('ReceiveMessage', (user, message) => {
this.messageSource.next({ user, message });
});
}
sendMessage(user: string, message: string) {
this.hubConnection.invoke('SendMessage', user, message)
.catch(err => console.error(err));
}
}
Step 3: Create Chat Component
ng generate component chat
File: chat.component.ts
import { Component, OnInit } from '@angular/core';
import { ChatService } from '../chat.service';
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.css']
})
export class ChatComponent implements OnInit {
user = '';
message = '';
messages: any[] = [];
constructor(private chatService: ChatService) {}
ngOnInit(): void {
this.chatService.startConnection();
this.chatService.message$.subscribe(msg => {
if (msg) this.messages.push(msg);
});
}
sendMessage() {
if (this.user && this.message) {
this.chatService.sendMessage(this.user, this.message);
this.message = '';
}
}
}
Step 4: Chat UI (HTML)
File: chat.component.html
<div class="container">
<h3>Mini Chat App</h3>
<input type="text" placeholder="Enter your name" [(ngModel)]="user">
<textarea placeholder="Type your message" [(ngModel)]="message"></textarea>
<button (click)="sendMessage()">Send</button>
<div class="messages">
<div *ngFor="let msg of messages">
<strong>{{msg.user}}:</strong> {{msg.message}}
</div>
</div>
</div>
Step 5: Styles (CSS)
File: chat.component.css
.container {
width: 400px;
margin: 20px auto;
border: 1px solid #ccc;
padding: 20px;
border-radius: 4px;
}
.messages {
margin-top: 20px;
height: 200px;
overflow-y: scroll;
border-top: 1px solid #ddd;
padding-top: 10px;
}
Step 6: Enable ngModel
In app.module.ts add:
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [BrowserModule, FormsModule],
})
Full Workflow Diagram
User → Angular → SignalR Service → ChatHub → Broadcast to All Clients → Angular → UI Update
Running the Application
Step 1: Run Backend
dotnet run
Step 2: Run Angular
ng serve
Open two browsers and test real-time chat.
Production-Level Improvements
Add JWT Authentication
Secure the chat by identifying each user.
Add Chat History
Store messages in SQL Server using EF Core.
Add Groups
Support private rooms using SignalR Groups APIs.
Scale Out
Use Redis backplane.
Deploy
Host backend on IIS or Azure App Service and Angular on CDN.
Conclusion
This is a full, production-ready mini chat application using Angular and ASP.NET Core SignalR. You now understand how to build connections, exchange real-time messages, and prepare the system for enterprise-level scenarios. If you want, we can extend this article with authentication, chat rooms, or database message storage.