Aspnet Signalr
title: ASP.NET Core SignalR — Complete Guide to Real-Time Communication description: 'Learn ASP.NET Core SignalR: WebSocket connections, hubs, real-time messaging, group management, scaling with Redis backplane, and building live dashboards.' date: 2026-06-28 lastmod: 2026-06-28 weight: 28 tags: [backend, aspnet]
ASP.NET Core SignalR enables real-time web functionality, pushing content from server to connected clients over WebSocket (with fallback transports) for live updates.
## What You'll Learn
By the end of this tutorial, you'll create SignalR hubs, send messages from server to clients, manage groups, build real-time dashboards, scale with Redis backplane, and handle connection events.
## Real-World Use
A stock trading platform uses SignalR to push price updates to hundreds of simultaneous users. Each user sees real-time price changes without refreshing the page.
## SignalR Learning Path
```mermaid
flowchart LR
A[Minimal API] --> B[SignalR]
B --> C[Testing]
C --> D[Logging]
D --> E[Health Checks]
B --> F{You Are Here}
style F fill:#f90,color:#fff
SignalR Hub
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
private readonly ILogger<ChatHub> _logger;
public ChatHub(ILogger<ChatHub> logger) => _logger = logger;
public async Task SendMessage(string user, string message)
{
_logger.LogInformation("Message from {User}: {Message}", user, message);
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public override async Task OnConnectedAsync()
{
_logger.LogInformation("Client connected: {ConnectionId}", Context.ConnectionId);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? exception)
{
_logger.LogInformation("Client disconnected: {ConnectionId}", Context.ConnectionId);
await base.OnDisconnectedAsync(exception);
}
}
SignalR Configuration
// Program.cs
builder.Services.AddSignalR(options =>
{
options.EnableDetailedErrors = builder.Environment.IsDevelopment();
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
});
builder.Services.AddCors(options => options.AddDefaultPolicy(policy =>
policy.AllowAnyHeader().AllowAnyMethod().AllowCredentials().SetIsOriginAllowed(_ => true)));
var app = builder.Build();
app.UseCors();
app.MapHub<ChatHub>("/hubs/chat");
// MapHub<ChatHub>("/hubs/chat").RequireAuthorization(); // With auth
Client-Side JavaScript
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect([0, 2000, 5000, 10000])
.build();
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = `${user}: ${message}`;
document.getElementById("messages").appendChild(li);
});
connection.start().then(() => {
document.getElementById("sendBtn").addEventListener("click", () => {
const user = document.getElementById("userInput").value;
const msg = document.getElementById("msgInput").value;
connection.invoke("SendMessage", user, msg);
});
}).catch(err => console.error(err));
Groups
public class NotificationHub : Hub
{
// Join a group (e.g., "user-123" for per-user notifications)
public async Task JoinGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
}
public async Task LeaveGroup(string groupName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
}
}
// Server-side: send to a specific group
public class NotificationService
{
private readonly IHubContext<NotificationHub> _hubContext;
public NotificationService(IHubContext<NotificationHub> hub) => _hubContext = hub;
public async Task NotifyUser(string userId, string message)
{
await _hubContext.Clients.Group($"user-{userId}")
.SendAsync("ReceiveNotification", message);
}
public async Task BroadcastToAll(string message)
{
await _hubContext.Clients.All.SendAsync("ReceiveNotification", message);
}
}
Scaling with Redis Backplane
dotnet add package Microsoft.AspNetCore.SignalR.StackExchangeRedis
builder.Services.AddSignalR()
.AddStackExchangeRedis("localhost:6379", options =>
{
options.Configuration.ChannelPrefix = "SignalR";
});
// Multiple server instances share messages via Redis pub/sub
Common Mistakes
1. Not Handling Disconnections
SignalR clients disconnect unexpectedly. Implement OnDisconnectedAsync to clean up group memberships.
2. Ignoring Connection Security
Without authentication, anyone can connect. Use RequireAuthorization() on the hub endpoint.
3. Blocking in Hub Methods
Hub methods should be async. Blocking calls block all messages on that connection.
4. Not Configuring CORS
Browser-based SignalR clients need CORS configured with AllowCredentials().
5. Sending Too Much Data
Large messages (>32KB) may be rejected. Send only necessary data, not full objects.
Practice Questions
1. What transport does SignalR use by default?
WebSocket. Falls back to Server-Sent Events, then Long Polling if WebSocket isn't available.
2. How does SignalR handle reconnection?
Configure automatic reconnect with withAutomaticReconnect() on the client.
3. What is a SignalR group?
A named collection of connections. Messages sent to a group reach only members of that group.
4. How do you scale SignalR across multiple servers?
Use a Redis backplane (AddStackExchangeRedis). Servers share messages through Redis pub/sub.
5. Challenge: Create a hub that broadcasts real-time stock price updates to all connected clients.
public class StockHub : Hub { }
// Background service
public class StockService : BackgroundService
{
private readonly IHubContext<StockHub> _hub;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await _hub.Clients.All.SendAsync("PriceUpdate", new { Symbol = "AAPL", Price = Random.Shared.NextDouble() * 100 });
await Task.Delay(1000, stoppingToken);
}
}
}
FAQ
Mini Project: Real-Time Notification Hub
Build a SignalR notification system that pushes updates to specific users.
public class NotificationHub : Hub
{
public async Task Register() => await Groups.AddToGroupAsync(Context.ConnectionId, Context.UserIdentifier);
}
app.MapHub<NotificationHub>("/hubs/notifications").RequireAuthorization();
// Notify specific user: _hubContext.Clients.User(userId).SendAsync("Notify", message);
What's Next
ASP.NET Core Testing ASP.NET Core Logging
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro