Get Number of Listeners, Clients Connected to Signalr Hub

Get number of listeners, clients connected to SignalR hub

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.

Count and list connectees in SignalR

Absolutely there is a way.

A lot of people handle this by creating a singleton class that contains a concurrent dictionary of any custom user object you define. If you add your custom user objects to this dictionary on connection and remove them on disconnection, you'll be able to query your dictionary for a count of active users. Please keep in mind that it may not be up to the second accurate, because there is roughly a 30 second "abort" window that may still be active, even if the client no longer is because they closed their browser.

Now, is there any real "hardbaked" functionality in SignalR to do this for you? Not that I'm aware, but I haven't looked into 2.0 too exhaustively yet. As for detecting disconnections, it is fairly robust and if a connection is not detected, it will remove the connection as mentioned, allowing you to keep on top of the disconnections.

There is an excellent tutorial describing this approach here:

http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20

SignalR send duplicate message to same user n times n is number of users connected .NetCore

as you have mentioned, the problem is RegisterNotification is being called everytime an instance of MessageHub is created. Instead of this, you can create background service and register to SqlDependency there and send the events using IHubContext. And after every notification, you call RegisterNotification again, which might cause the duplication as well.

  • https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
  • https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext

I haven't tested this code, but here is an example:

public class EventBroadcaster : IHostedService
{
private readonly IHubContext<MessageHub> _hubContext;
private readonly string _connectionString;

public EventBroadcaster(
IConfiguration configuration,
IHubContext<MessageHub> hubContext)
{
_hubContext = hubContext;
_connectionString = // Get Connection String from configuration
}

public Task StartAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Started event broadcasting service");

RegisterNotification();
return Task.CompletedTask;
}

public void RegisterNotification()
{
using (SqlConnection con = new SqlConnection(_connectionString))
{
SqlCommand cmd = new SqlCommand(sqlCommand, con);

if (con.State != System.Data.ConnectionState.Open)
{
con.Open();
}

cmd.Notification = null;

SqlDependency sqlDep = new SqlDependency(cmd);

sqlDep.OnChange += sqlDep_OnChange;

using (SqlDataReader reader = cmd.ExecuteReader())
{
// nothing need to add here now
}
}
}

static int count = 1;
private async void sqlDep_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change )
{
SqlDependency sqlDep = sender as SqlDependency;
sqlDep.OnChange -= sqlDep_OnChange;

await _hubContext.Clients.User("64ed09d7-255f-4aae-a25f-7a50e59943b4").SendAsync("abc", "hello"+count);

count += 1;
}
}

public Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Event Broadcasting Service is stopping.");

// TODO: Stop listening to SqlDependency notifications

return Task.CompletedTask;
}

Show connected ids of clients in a Gridview or a listbox winform using SIgnalR

Try to remove the first and second line in your button2_Click method. You already added the connectionIds to your UserHandler instance in your overridden OnConnected method.

//edit
I have not changed anything at your code. I don't know how you still get an error.
Test

//edit
You already have the connectionIds in your list? Why not using them? This will add the connectionIds to your datagrid. If you need more information like the username you could replace ConnectedIds in your UserHandler with a class with two properties username and connectionId.

if (UserHandler.ConnectedIds.Count != 0)
{
foreach(var connectionId in UserHandler.ConnectedIds)
{
dataGridView1.Rows.Add(connectionId);
}
}


Related Topics



Leave a reply



Submit