Course contentsShow
← C#
Lesson 1497 of 1,90813. Real-time Communication with SignalRFree lesson

Managing Hub Life-Cycle Events

Hook into custom lifecycle events to track user presence and connectivity status.

In this lesson, you will learn how to hook into SignalR’s built-in lifecycle events to accurately track user presence and manage real-time connectivity status.

When working with real-time systems, knowing exactly when a user connects or disconnects is critical for features like "online status" indicators or active session tracking. SignalR provides two primary hooks within your Hub class: OnConnectedAsync and OnDisconnectedAsync. These methods are automatically triggered by the SignalR infrastructure whenever a client establishes or terminates a connection.

Implementing Presence Tracking

To track user presence, you can override these methods to update your backing store—such as a database via Entity Framework or a distributed cache like Redis.

public class PresenceHub : Hub
{
    private readonly IUserPresenceService _presenceService;

    public PresenceHub(IUserPresenceService presenceService)
    {
        _presenceService = presenceService;
    }

    public override async Task OnConnectedAsync()
    {
        var userId = Context.UserIdentifier;
        await _presenceService.MarkOnline(userId, Context.ConnectionId);
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        var userId = Context.UserIdentifier;
        await _presenceService.MarkOffline(userId);
        await base.OnDisconnectedAsync(exception);
    }
}

Critical Considerations

When managing these events, keep in mind that OnDisconnectedAsync is not guaranteed to fire if the server process crashes or the network interface suddenly fails. Furthermore, because a single user might open multiple browser tabs, you may have multiple ConnectionId values associated with one UserIdentifier.

To maintain an accurate state, you should track these connections in a collection. When OnConnectedAsync triggers, increment a count or add the ConnectionId to a set; when OnDisconnectedAsync triggers, remove the specific ConnectionId. Only consider the user "offline" once their set of active connections is empty. This granular approach prevents a user from appearing offline simply because they closed one of three open browser tabs.

Key Takeaway: Use OnConnectedAsync and OnDisconnectedAsync to intercept connection state changes, but always account for multi-tab scenarios to ensure your user presence logic remains robust and accurate.