Get number of listeners, clients connected to SignalR hub

C#asp.netasp.net Mvc-3SignalrSignalr Hub

C# Problem Overview


Is there a way to find out the number of listeners (clients connected to a hub?)

I'm trying to run/start a task if at least one client is connected, otherwise do not start it:

[HubName("taskActionStatus")]
public class TaskActionStatus : Hub, IDisconnect
{
    static CancellationTokenSource tokenSource;
    
    public void GetTasksStatus(int? siteId)
    {
        tokenSource = new CancellationTokenSource();
        CancellationToken ct = tokenSource.Token;

        ITaskRepository taskRepository = UnityContainerSetup.Container.Resolve<ITaskRepository>();

        // init task for checking task statuses
        var tasksItem = new DownloadTaskItem();
        taskRepository.GetTasksStatusAsync(siteId, tasksItem, ct);

        // subscribe to event [ listener ]
        tasksItem.Changed += new EventHandler<TaskEventArgs>(UpdateTasksStatus);
    }

    public void UpdateTasksStatus(object sender, TaskEventArgs e)
    {
        Clients.updateMessages(e.Tasks);
    }

    // when browsing away from page
    public Task Disconnect()
    {
        try
        {
            tokenSource.Cancel();
        }
        catch (Exception)
        {
            //
        }
        
        return null;
    }
}

thanks

C# Solutions


Solution 1 - C#

There is no way to get this count from SignalR as such. You have to use the OnConnect() and OnDisconnect() methods on the Hub to keep the count yourself.

Simple example with a static class to hold the count:

public static class UserHandler
{
    public static HashSet<string> ConnectedIds = new HashSet<string>();
}

public class MyHub : Hub
{
    public override Task OnConnectedAsync()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId);
        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        UserHandler.ConnectedIds.Remove(Context.ConnectionId);
        return base.OnDisconnectedAsync(exception);
    }
}

You then get the count from UserHandler.ConnectedIds.Count.

Solution 2 - C#

For version 2.1.1< it should be:

public static class UserHandler
{
    public static HashSet<string> ConnectedIds = new HashSet<string>();
}

public class MyHub : Hub
{
    public override Task OnConnected()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId);
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        UserHandler.ConnectedIds.Remove(Context.ConnectionId);
        return base.OnDisconnected(stopCalled);
    }
}

Solution 3 - C#

In SIgnalR(version 2.4.1) it is rather easy:

public int GetOnline()
{
   return GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().Count;
}

Just Invoke this method from client (:

Solution 4 - C#

Now you need:

public override Task OnConnectedAsync()
{
    UserHandler.ConnectedIds.Add(Context.ConnectionId);

    return base.OnConnectedAsync();
}

public override Task OnDisconnectedAsync(Exception exception)
{
    UserHandler.ConnectedIds.Remove(Context.ConnectionId);
    return base.OnDisconnectedAsync(exception);
}

Solution 5 - C#

I would like to add that if you are using a serverless solution with Azure Functions and Azure SignalR Service there is the following resolved issue: https://github.com/Azure/azure-functions-signalrservice-extension/issues/54

It refers to this sample where you can use Event Grids to get the real-time count of connections, pretty sweet. https://github.com/aspnet/AzureSignalR-samples/tree/master/samples/EventGridIntegration

Solution 6 - C#

In my project which use Microsoft.AspNetCore.SignalR.Core version 1.1.0

I can debug and see the count with

((Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<XXX.Push.SignalR.EventHub>)((Microsoft.AspNetCore.SignalR.Internal.AllClientProxy<XXX.Push.SignalR.EventHub>)((Microsoft.AspNetCore.SignalR.TypedClientBuilder.IEventImpl)((Microsoft.AspNetCore.SignalR.Internal.HubClients<XXX.Push.SignalR.EventHub, XXX.Push.SignalR.IEvent>)_hub.Clients).All)._proxy)._lifetimeManager)._connections.Count

It looks like this:

debug

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShaneKmView Question on Stackoverflow
Solution 1 - C#Anders ArpiView Answer on Stackoverflow
Solution 2 - C#OgglasView Answer on Stackoverflow
Solution 3 - C#Лопатка ПодзаборнаяView Answer on Stackoverflow
Solution 4 - C#ejdrian313View Answer on Stackoverflow
Solution 5 - C#gerb0nView Answer on Stackoverflow
Solution 6 - C#我零0七View Answer on Stackoverflow