ASP.NET Core  

Mini Chat App (SignalR Basics) – Angular + ASP.NET Core

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:

  1. ASP.NET Core Web API with SignalR Hub

    • Manages chat connections

    • Stores connected user list

    • Broadcasts messages

  2. Angular Frontend

    • Connects to SignalR Hub

    • Sends and receives chat messages

    • Displays real-time updates

  3. Browser Clients

    • Multiple users chat in real time

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.