Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List of opened connections in SignalR?

How can I get a list of opened connections from SignalR without sending them a "ping" or manual registering them into own list?

UPDATE: Or just to get number of clients to which a message was sent from a hub. I want to know how many responses I should wait for (without waiting whole timeout).

(Since, SignalR does not support return values when calling clients from a hub, I am collecting results by another message that clients are sending to the hub.)

CLARIFICATION: I assume SignalR must know to which connections is sending a message.

like image 724
TN. Avatar asked Jul 14 '15 07:07

TN.


2 Answers

You can store user's id onConnected and remove it on disconnect. See this is only an example using a database to persist the connected ids

  protected Task OnConnected(IRequest request, string connectionId){
    var context=new dbContext();
    context.Connections.Add(connectionId);
    context.Save();
  }
  protected Task OnDisconnected(IRequest request, string connectionId){        
    var context=new dbContext();
    var id=context.Connections.FirstOrDefault(e=>e.connectionId==connectionId);
    context.Connections.Remove(id);
    context.Save();
  } 

then everywhere you need to access the list of connected ids, you request your db.

like image 137
Bellash Avatar answered Oct 10 '22 04:10

Bellash


I haven't yet found any direct way of doing that.

The best I have come up so far is following the tutorial - USERS BY CONNECTIONS IN SIGNALR, you can find more code in the link, I have simplified it for basic understanding.

public void Register(HubClientPayload payload, string connectionId)
{       
    lock (_lock)
    {
        List<String> connections;
        if (_registeredClients.TryGetValue(payload.UniqueID, out connections))
        {
             if (!connections.Any(connection => connectionID == connection))
             {
                 connections.Add(connectionId);
             }
        }
        else
        {
             _registeredClients[payload.UniqueID] = new List<string> { connectionId };
        }
    }        
}

and

public Task Disconnect(string connectionId)
{       
    lock (_lock)
    {
         var connections = _registeredClients.FirstOrDefault(c => c.Value.Any(connection => connection == connectionId));     
         // if we are tracking a client with this connection remove it
         if (!CollectionUtil.IsNullOrEmpty(connections.Value))
         {
            connections.Value.Remove(connectionId);     
            // if there are no connections for the client, remove the client from the tracking dictionary
            if (CollectionUtil.IsNullOrEmpty(connections.Value))
            {
                _registeredClients.Remove(connections.Key);
            }
         }                 
    return null;
}

also,

public Task Reconnect(string connectionId)
{
   Context.Clients[connectionId].reRegister();       
   return null;
}
like image 21
Rohit Vipin Mathews Avatar answered Oct 10 '22 05:10

Rohit Vipin Mathews