SignalR Hubs & Connections
Create a SignalR hub, map it in ASP.NET Core, and establish WebSocket connections from JavaScript and .NET clients.
SignalR Hubs & Connections is a free C# Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is SignalR?
SignalR is an ASP.NET Core library that adds real-time, bidirectional communication between server and clients. It automatically picks the best transport — WebSockets, Server-Sent Events, or Long Polling — based on what both sides support.
Setting Up SignalR
Add SignalR to services and map a hub endpoint. A hub is a class that handles client connections and method calls.
builder.Services.AddSignalR();
var app = builder.Build();
app.UseCors("AllowAll");
app.MapHub<ChatHub>("/hubs/chat");
app.Run();Creating a Hub
Inherit from Hub. Hub methods are called by clients. The Context property provides connection info, and Clients lets you send messages back.
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
// Broadcast to ALL connected clients
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public override async Task OnConnectedAsync()
{
await Clients.Caller.SendAsync("Welcome",
$"Connected as {Context.ConnectionId}");
await base.OnConnectedAsync();
}
}JavaScript Client
The official SignalR JavaScript client builds a connection, registers event handlers, and starts the connection. Methods defined on the hub are callable from JavaScript.
// npm install @microsoft/signalr
import * as signalR from "@microsoft/signalr";
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect()
.build();
connection.on("ReceiveMessage", (user, message) => {
console.log(`${user}: ${message}`);
});
await connection.start();
await connection.invoke("SendMessage", "Alice", "Hello!");.NET SignalR Client
The .NET client works the same way — useful for service-to-service real-time communication or desktop/mobile apps.
// dotnet add package Microsoft.AspNetCore.SignalR.Client
var connection = new HubConnectionBuilder()
.WithUrl("https://myapp.com/hubs/chat")
.WithAutomaticReconnect()
.Build();
connection.On<string, string>("ReceiveMessage", (user, msg) =>
Console.WriteLine($"{user}: {msg}"));
await connection.StartAsync();
await connection.InvokeAsync("SendMessage", "Bot", "Connected!");Sending to Specific Clients
The Clients property has methods to target specific connections, callers, or all connected clients except specified ones.
// To the caller only
await Clients.Caller.SendAsync("YouSaid", message);
// To a specific connection
await Clients.Client(connectionId).SendAsync("PrivateMsg", msg);
// To all except caller
await Clients.Others.SendAsync("ReceiveMessage", user, message);
// To multiple specific connections
await Clients.Clients(new[] { id1, id2 })
.SendAsync("DirectMsg", msg);Hub Context: Sending from Outside the Hub
Inject IHubContext<T> into services or background workers to send messages from outside the hub class — essential for server-initiated pushes.
public class NotificationService
{
private readonly IHubContext<ChatHub> _hub;
public NotificationService(IHubContext<ChatHub> hub) => _hub = hub;
public async Task BroadcastAlertAsync(string alert)
{
// Send to all clients from a background service
await _hub.Clients.All.SendAsync("SystemAlert", alert);
}
}Connection Lifecycle Events
Override OnConnectedAsync and OnDisconnectedAsync to track connections, maintain state, or clean up resources.
public override async Task OnConnectedAsync()
{
_connections.TryAdd(Context.ConnectionId, GetUserName());
await Clients.All.SendAsync("UserJoined", GetUserName());
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? ex)
{
_connections.TryRemove(Context.ConnectionId, out var user);
await Clients.All.SendAsync("UserLeft", user);
await base.OnDisconnectedAsync(ex);
}
private string GetUserName() =>
Context.User?.Identity?.Name ?? Context.ConnectionId;Automatic Reconnect
Enable automatic reconnect on the client to handle transient disconnections gracefully. You can customize the retry delays.
// JavaScript client
const conn = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect([0, 2000, 5000, 10000, 30000]) // retry delays in ms
.build();
conn.onreconnecting(err => console.warn("Reconnecting...", err));
conn.onreconnected(id => console.log("Reconnected:", id));
conn.onclose(err => console.error("Disconnected:", err));Authentication with SignalR
SignalR honours ASP.NET Core authentication middleware. Add [Authorize] to the hub class or use the JWT handler that supports query-string tokens (needed for WebSocket authentication).
[Authorize]
public class PrivateHub : Hub
{
public Task SendMessage(string msg)
{
var user = Context.User!.Identity!.Name;
return Clients.All.SendAsync("Msg", user, msg);
}
}
// JWT via query string (WebSocket requirement):
builder.Services.AddAuthentication().AddJwtBearer(opt =>
{
opt.Events = new JwtBearerEvents
{
OnMessageReceived = ctx =>
{
var token = ctx.Request.Query["access_token"];
if (!string.IsNullOrEmpty(token))
ctx.Token = token;
return Task.CompletedTask;
}
};
});Quick Check
How do you send a SignalR message from a background service (outside the hub class)?
Recap: SignalR Hubs & Connections
Key takeaways:
- SignalR picks the best transport (WebSockets, SSE, Long Polling) automatically
- Hub methods are callable by clients;
Clients.*targets specific recipients - Inject
IHubContext<T>to push messages from outside the hub - Override
OnConnectedAsync/OnDisconnectedAsyncfor lifecycle management - Use
withAutomaticReconnect()for resilient client connections - JWT auth via query string is required for WebSocket connections
Frequently asked questions
Is the “SignalR Hubs & Connections” lesson free?
Yes — the full text of “SignalR Hubs & Connections” is free to read here on the web, and the C# Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.
What will I learn in “SignalR Hubs & Connections”?
Create a SignalR hub, map it in ASP.NET Core, and establish WebSocket connections from JavaScript and .NET clients. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C# Academy?
No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “SignalR Hubs & Connections” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C# Academy lesson?
Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- SignalR Hubs & Connections
- Groups, Users & Connection Management
- Strongly Typed Hubs
- Scaling with Redis Backplane