What is "OnDisconnected" in SignalR?
1 Answer
In SignalR, OnDisconnected (or OnDisconnectedAsync in ASP.NET Core SignalR) is a hub lifecycle method that is called when a client connection is terminated.
ASP.NET Core SignalR
You override OnDisconnectedAsync in your Hub:
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
public override async Task OnDisconnectedAsync(Exception? exception)
{
string connectionId = Context.ConnectionId;
Console.WriteLine($"Client disconnected: {connectionId}");
await base.OnDisconnectedAsync(exception);
}
}
When it is called
The method runs when a client disconnects for reasons such as:
- The user closes the browser/tab.
- The client explicitly stops the SignalR connection.
- A network interruption causes the connection to end.
- The server disconnects the client.
- A connection timeout occurs.
The exception parameter
public override async Task OnDisconnectedAsync(Exception? exception)
{
if (exception != null)
{
Console.WriteLine($"Disconnected due to error: {exception.Message}");
}
await base.OnDisconnectedAsync(exception);
}
exception == null usually indicates a normal disconnect.
A non-null exception may indicate an unexpected termination or transport error.
Common uses
Track online users
public override async Task OnDisconnectedAsync(Exception? exception)
{
OnlineUsers.Remove(Context.ConnectionId);
await base.OnDisconnectedAsync(exception);
}
Remove users from custom tracking
public override async Task OnDisconnectedAsync(Exception? exception)
{
_connectionManager.RemoveConnection(Context.ConnectionId);
await base.OnDisconnectedAsync(exception);
}
Notify other clients
public override async Task OnDisconnectedAsync(Exception? exception)
{
await Clients.All.SendAsync(
"UserDisconnected",
Context.ConnectionId);
await base.OnDisconnectedAsync(exception);
}
Relationship with OnConnectedAsync
A typical connection lifecycle looks like:
Client connects
↓
OnConnectedAsync()
↓
Client invokes hub methods
↓
Connection ends
↓
OnDisconnectedAsync()
Older ASP.NET SignalR
In classic ASP.NET SignalR, the method was:
public override Task OnDisconnected(bool stopCalled)
{
return base.OnDisconnected(stopCalled);
}
In ASP.NET Core SignalR, it became:
public override Task OnDisconnectedAsync(Exception? exception)
{
return base.OnDisconnectedAsync(exception);
}
So OnDisconnectedAsync is the place to perform cleanup, update user presence, release resources, and notify other clients when a SignalR connection ends.