SignalR Real-Time Communication, Hubs & Chat Masterclass
Welcome to Phase 16 (Chapter 45): ASP.NET Core SignalR โ Real-Time Hubs, Chat & Live Notifications Masterclass! SignalR is Microsoft's real-time communication library for ASP.NET Core that enables servers to push data to connected clients instantly โ without clients polling. Built on WebSockets (with SSE and Long Polling fallbacks), SignalR powers chat apps, live dashboards, stock tickers, collaborative editing, and notification systems.
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
// Called by a client when they send a message
public async Task SendMessage(string user, string message)
{
// Broadcast to ALL connected clients
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
// Join a specific group (chat room)
public async Task JoinRoom(string roomName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, roomName);
await Clients.Group(roomName).SendAsync("ReceiveMessage", "System",
Context.ConnectionId + " joined " + roomName);
}
// Send to specific group only
public async Task SendToRoom(string roomName, string user, string message)
{
await Clients.Group(roomName).SendAsync("ReceiveMessage", user, message);
}
// Lifecycle events
public override async Task OnConnectedAsync()
{
Console.WriteLine("Client connected: " + Context.ConnectionId);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? exception)
{
Console.WriteLine("Client disconnected: " + Context.ConnectionId);
await base.OnDisconnectedAsync(exception);
}
}
// Program.cs โ Register SignalR
builder.Services.AddSignalR();
app.MapHub<ChatHub>("/hubs/chat");
// Install: npm install @microsoft/signalr
import * as signalR from "@microsoft/signalr";
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect()
.build();
// Listen for messages from server
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = user + ": " + message;
document.getElementById("messagesList").appendChild(li);
});
// Start connection
await connection.start();
console.log("SignalR connected!");
// Send message
document.getElementById("sendBtn").addEventListener("click", async () => {
const user = document.getElementById("userInput").value;
const message = document.getElementById("messageInput").value;
await connection.invoke("SendMessage", user, message);
});
Q1: Does SignalR always use WebSockets?
SignalR automatically negotiates the best transport available: WebSockets (preferred, full-duplex, lowest latency), Server-Sent Events (server-to-client only), or Long Polling (HTTP fallback for restrictive environments). You can force WebSockets-only via configuration.
Q2: How does SignalR scale across multiple servers?
Use Azure SignalR Service or a Redis backplane to coordinate messages across multiple server instances. Without a backplane, clients connected to different server pods won't receive each other's messages.