What it is
SignalR adds real-time bidirectional communication to ASP.NET Core, negotiating WebSockets where available and falling back automatically.
Define a Hub with methods clients can call, and push to clients through strongly-typed interfaces. Groups let you address subsets of connections.
Installation
Included in ASP.NET CoreGetting started
The smallest useful thing you can do with it, and what each part means.
csharp
public interface IBookClient
{
Task BookAdded(BookDto book);
Task BookRemoved(int id);
}
public class BookHub : Hub<IBookClient>
{
public async Task JoinLibrary(string libraryId) =>
await Groups.AddToGroupAsync(Context.ConnectionId, libraryId);
public override async Task OnDisconnectedAsync(Exception? ex)
{
await base.OnDisconnectedAsync(ex);
}
}
app.MapHub<BookHub>("/hubs/books");
// Push from anywhere via the injected context.
await _hub.Clients.Group(libraryId).BookAdded(dto);Advanced usage
Where the library earns its place over a simpler alternative.
csharp
// Multiple servers need a backplane, or a message published on
// instance A never reaches a client connected to instance B.
builder.Services.AddSignalR()
.AddStackExchangeRedis(redisConnectionString);
// Client
const connection = new signalR.HubConnectionBuilder()
.withUrl('/hubs/books')
.withAutomaticReconnect([0, 2000, 10000, 30000])
.build();
connection.on('BookAdded', (book) => render(book));
connection.onreconnected(() => connection.invoke('JoinLibrary', libraryId));Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Messages reach only some clients
- Multiple server instances with no backplane. Add Redis or Azure SignalR Service.
- Clients stop receiving after a network blip
- They reconnected but did not rejoin their groups. Handle onreconnected.
Best practices
- Use Hub<TClient> for compile-time checked client method names.
- Add a Redis backplane before scaling beyond a single instance.
- Re-join groups in the client's onreconnected handler; membership does not survive a reconnect.
- Authorise hub methods; a hub is a public endpoint like any controller.
Background
Why it exists, and what it was reacting to.
SignalR abstracts over the transport problem: it prefers WebSockets, falls back to server-sent events or long polling, and handles reconnection, so applications do not implement three code paths.
