Real-Time Communication with SignalR
Build live chat, dashboards, and notifications that push updates to clients instantly — no polling required.
What You'll Learn
- • Create SignalR hubs with groups, private messages, and lifecycle events
- • Build strongly-typed hubs for compile-time safety
- • Connect JavaScript clients with automatic reconnection
- • Send messages from controllers via
IHubContext
📡 Real-World Analogy
Traditional HTTP is like sending letters — the client asks, the server responds. SignalR is like a phone call — once connected, both sides can talk anytime. Groups are like conference calls where only members hear the conversation. SignalR automatically picks the best transport (WebSockets, Server-Sent Events, or Long Polling).
Creating a SignalR Hub
A Hub is the central class that clients connect to. It handles sending messages to all clients, groups, or specific users. You also get lifecycle hooks for connect/disconnect events.
SignalR Hub with Groups & Lifecycle
Build a chat hub with rooms, private messaging, and connection tracking.
using Microsoft.AspNetCore.SignalR;
// ChatHub.cs — Server-side hub
public class ChatHub : Hub
{
// Called when a client sends a message
public async Task SendMessage(string user, string message)
{
// Broadcast to ALL connected clients
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
// Send to specific group (e.g., a chat room)
public async Task JoinRoom(string roomName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, roo
...Strongly-Typed Hubs
Magic strings like "ReceiveMessage" are error-prone. Strongly-typed hubs use an interface to define client methods, giving you compile-time safety and IntelliSense.
Typed Hub & IHubContext
Use interfaces for type-safe client communication and send from controllers.
using Microsoft.AspNetCore.SignalR;
// Strongly-typed hub — compile-time safety
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
Task UserConnected(string connectionId);
Task UserDisconnected(string connectionId);
Task ReceiveNotification(Notification notification);
}
public class TypedChatHub : Hub<IChatClient>
{
// No more magic strings!
public async Task SendMessage(string user, string message)
{
// Clients.All now has type
...JavaScript Client Connection
The SignalR JavaScript client handles connection, automatic reconnection, and event registration. Always register handlers before calling start().
JavaScript SignalR Client
Connect to the hub with automatic reconnection and event handlers.
// JavaScript client — connecting to SignalR hub
// Install: npm install @microsoft/signalr
import * as signalR from "@microsoft/signalr";
// Build connection
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat", {
accessTokenFactory: () => localStorage.getItem("token") ?? ""
})
.withAutomaticReconnect([0, 2000, 5000, 10000, 30000]) // Retry intervals
.configureLogging(signalR.LogLevel.Information)
.build();
// Register event handlers BEFORE
...Pro Tip
For production apps with multiple servers, configure a Redis backplane so messages are shared across all server instances: builder.Services.AddSignalR().AddStackExchangeRedis("redis-connection-string").
Common Mistakes
- • Registering event handlers after
start()— events during connection are missed - • Not using
withAutomaticReconnect— connection drops silently - • Storing
ConnectionIdlong-term — it changes on every reconnect
Lesson Complete!
You've built real-time features with SignalR. Next, dive into raw WebSockets and streaming data in .NET.
Sign up for free to track which lessons you've completed and get learning reminders.