SignalR - Checking if a user is still connected

前端 未结 4 811
谎友^
谎友^ 2020-12-09 11:23

I have a hub with method that is called client-side. This method launches a timer with a delegate that runs every 10 seconds. Since it wouldn\'t make sense to keep running t

相关标签:
4条回答
  • 2020-12-09 11:42

    I have done this way:

    public class PrincipalCommunicator
        {
            public readonly static Lazy<PrincipalCommunicator> _instance = new Lazy<PrincipalCommunicator>(
                    () => new PrincipalCommunicator(GlobalHost.ConnectionManager.GetHubContext<PrincipalHub>())
                );
    
            public List<string> ConnectedUsers { get; set; }
    
            private IHubContext _context;
    
            private PrincipalCommunicator(IHubContext context)
            {
                ConnectedUsers = new List<string>();
                _context = context;
            }
    
            public static PrincipalCommunicatorInstance
            {
                get
                {
                    return _instance.Value;
                }
            }
    
            public bool IsUserConnected(string user)
            {
                return UsuariosConectados.Contains(user);
            }
        }
    
        public class PrincipalHub : Hub
        {
            public override Task OnConnected()
            {
                PrincipalComunicador.Instance.UsuariosConectados.Add(Context.User.Identity.Name);
    
                return base.OnConnected();
            }
    
            public override Task OnDisconnected(bool stopCalled)
            {
                PrincipalComunicador.Instance.UsuariosConectados.Remove(Context.User.Identity.Name);
                return base.OnDisconnected(stopCalled);
            }
        }
    }
    

    This way, all logic to send something to client stays in one place, like the example and you can know if a user is connected anywhere in the code.

    0 讨论(0)
  • 2020-12-09 11:45

    Probably the most used solution is to keep a static variable containing users currently connected and overriding OnConnect and OnDisconnect or implementing IDisconnect depending on the version that you use.

    You would implement something like this:

    public class MyHub : Hub
    {
        private static List<string> users = new List<string>();
        public override Task OnConnected()
        {
            users.Add(Context.ConnectionId);
            return base.OnConnected();
        }
    
        //SignalR Verions 1 Signature
        public override Task OnDisconnected()
        {
            users.Remove(Context.ConnectionId);
            return base.OnDisconnected();
        }
    
        //SignalR Version 2 Signature
        public override Task OnDisconnected(bool stopCalled)
        {
            users.Remove(Context.ConnectionId);
            return base.OnDisconnected(stopCalled);
        }
    
        // In your delegate check the count of users in your list.
    }
    
    0 讨论(0)
  • 2020-12-09 11:50

    If you save your connectionId in your database, you can check this:

    var heartBeat = GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>();
    
    var connectionAlive = heartBeat.GetConnections().FirstOrDefault(c=>c.ConnectionId == connection.ConnectionId);
    
    if (connectionAlive.IsAlive)
    {
    //Do whatever...
    }
    
    0 讨论(0)
  • 2020-12-09 11:57

    From http://forums.asp.net/t/1829432.aspx/1?How+do+I+get+list+of+connected+clients+on+signalr+

    IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
    context.Clients.notify("Hello world");
    

    So you should be able to get context.Clients.Count.

    That post also references the wiki which has lots of good info. You could try using the OnConnected/OnDisconnected examples to track the users, and when you get to zero users stop your call.

    0 讨论(0)
提交回复
热议问题