C# SignalR - 检查用户是否仍处于连接状态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13692069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SignalR - Checking if a user is still connected
提问by edobry
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?
我有一个带有称为客户端的方法的集线器。此方法使用每 10 秒运行一次的委托启动一个计时器。由于在没有人连接到集线器的情况下继续运行此委托是没有意义的,因此我想在重新安排它之前检查是否仍有用户从委托内部连接。有没有办法做到这一点?
采纳答案by cillierscharl
Probably the most used solution is to keep a static variable containing users currently connected and overriding OnConnectand OnDisconnector implementing IDisconnectdepending on the version that you use.
可能最常用的解决方案是保留一个包含当前连接的用户的静态变量,OnConnect并根据您使用的版本覆盖和/OnDisconnect或实现IDisconnect。
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.
}
回答by Tim Hobbs
From http://forums.asp.net/t/1829432.aspx/1?How+do+I+get+list+of+connected+clients+on+signalr+
来自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.
所以你应该能够得到context.Clients.Count。
That post also references the wikiwhich 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.
那篇文章还引用了维基,其中有很多很好的信息。您可以尝试使用 OnConnected/OnDisconnected 示例来跟踪用户,当您达到零用户时停止您的呼叫。
回答by chemitaxis
If you save your connectionId in your database, you can check this:
如果您将 connectionId 保存在数据库中,则可以检查以下内容:
var heartBeat = GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>();
var connectionAlive = heartBeat.GetConnections().FirstOrDefault(c=>c.ConnectionId == connection.ConnectionId);
if (connectionAlive.IsAlive)
{
//Do whatever...
}
回答by VGs
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 exampleand you can know if a user is connected anywhere in the code.
这样,向客户端发送内容的所有逻辑都停留在一个地方,就像示例一样,您可以知道用户是否连接到代码中的任何位置。

