2012-12-03 104 views
8

我有一个称为客户端的方法的集线器。此方法启动一个具有每10秒运行一次委托的计时器。由于如果没有人连接到集线器,继续运行此代理是没有意义的,我想在重新安排它之前检查是否有任何用户仍然从代理内部连接。有没有办法做到这一点?SignalR - 检查用户是否仍然连接

回答

16

也许是最常用的解决办法是保持一个静态的用户变量包含当前连接的和压倒一切的OnConnectOnDisconnect或根据您使用的版本实现IDisconnect

你会实现这样的事情:

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) 
    { 
     return base.OnDisconnected(stopCalled); 
    } 

    // In your delegate check the count of users in your list. 
} 
+0

我在其他地方看到过这个,只是希望有更好的方法。谢谢,我会试试它! – edobry

+2

尝试访问单个资源的多个线程是否存在并发问题? –

+3

这不但不能可靠地工作,因为集线器的寿命模型,它打破了用背板扩展的可能性。唯一真正的答案是跟踪像redis或appfabric这样的共享缓存中的在线状态。 – Bon

1

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"); 

所以,你应该能够得到context.Clients.Count。

该帖子还引用了wiki,它有很多很好的信息。您可以尝试使用OnConnected/OnDisconnected示例来跟踪用户,当您达到零用户时停止您的呼叫。

+0

感谢您的建议,但我试图做这来自一个中心内......它仍然会工作吗? – edobry

10

如果您保存您的ConnectionId在你的数据库,你可以检查此:

var heartBeat = GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>(); 

var connectionAlive = heartBeat.GetConnections().FirstOrDefault(c=>c.ConnectionId == connection.ConnectionId); 

if (connectionAlive.IsAlive) 
{ 
//Do whatever... 
} 
+1

你需要添加'使用Microsoft.AspNet.SignalR.Transports' –

+0

也不应该.Transports是在核心大会......无赖!请参阅:https://msdn.microsoft.com/en-us/library/microsoft.aspnet.signalr.transports.transportmanager%28v=vs.118%29.aspx?f=255&MSPPError=-2147217396 –

相关问题