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 this delegate if no one is connected to the hub, I want to check if any users are still connected from inside the delegate before I reschedule it. Is there any way to do this?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.
}
Method 2
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...
}
Method 3
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.
Method 4
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.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0