2013-03-04 69 views
5

我需要检查一个特定的用户是否仍然连接。signalR跟踪连接的用户

我有以下HashSet的,用于跟踪用户的:

public static class UserHandler 
{ 
    public static HashSet<string> ConnectedIds = new HashSet<string>(); 
} 

于是就断开:

public override Task OnDisconnected() 
    { 
     UserHandler.ConnectedIds.Remove(this.Context.ConnectionId); 
     if (UserHandler.ConnectedIds.Count == 0) 
     { 
       // STOP TASK -> SET CANCELLATION 
     } 
     return base.OnDisconnected(); 
    } 

,并在连接:

public override Task OnConnected() 
    { 
     Logger.Log.file.Info("[TaskActionStatus HUB => OnConnected] Start"); 

     UserHandler.ConnectedIds.Add(this.Context.ConnectionId); 

     // start task only if at least one listener 
     if (UserHandler.ConnectedIds.Count < 2) 
     { 
      // START A TASK -> (WHILE LOOP THAT GETS DATA FROM DB EVERY 2 SEC) 
     } 

     return base.OnConnected(); 
    } 

现在,问题出现时,用户只需关闭他/她的浏览器窗口即可。我无法知道他/她是否断开连接。

因此根据一些问题here,我会打电话给每个客户端并获得响应。我不知道该怎么做。

我想我会有这样的:

public static void CheckConnectedUsers() 
{ 
    var context = GlobalHost.ConnectionManager.GetHubContext<TaskActionStatus>(); 
    foreach (var connection in UserHandler.ConnectedIds) 
    { 
     context.Clients.Client(connection).verifyConnected("online?"); 
    } 
} 

但我如何获得回应形成的客户端?

编辑:正在执行 步骤:

我需要,因为连接的用户的确切数目。如果有至少一个用户连接我要开始的任务。我想确保所有连接用户只有1个任务正在运行(启动任务)。假设这样的情况:2个用户查看使用signalR的页面。 HashSet现在包含2个ids,一个任务正在运行。关闭他/她的浏览器,几秒钟后又刷新他/她的浏览器。现在,第一个(关闭他/她的浏览器的程序没有执行OnDisconnected方法,所以HashSet仍然有他/她的ConnectionId,而且“刷新”的程序确实执行了OnDisonnected,然后OnConnected将它的connectionId添加到HashSet。在一个HashSet只有1的ConnectionId和启动任务,HashSet的包含2个(老不再连接,并且刚刚更新了他/她的浏览器中的一个),任务从来没有得到重新启动。

感谢

回答

6

使用SignalR 1.0,OnDisconnected应该始终启动,即使用户关闭了窗口(如果服务器重新启动,则例外)

OnDisconnected可能不会立即触发,因为如果客户端不“中止”连接,它将被视为“不干净”,因为客户端可能尝试并重新连接(如果您重新连接,则根据SignalR的语义没有断开连接) 。

默认情况下,服务器调用OnDisconnected大约需要30秒来进行“不干净”断开连接。这可以通过GlobalHost.Configuration.DisconnectTimeout重新配置。

+0

事情是,我需要连接的用户的确切数量,因为如果至少有一个用户连接我需要启动一项任务。我想确保所有连接用户只有一个任务正在运行<2(启动任务)。假设这种情况:2个用户查看使用signalR的页面。 HashSet现在包含2个ID。关闭他/她的浏览器,几秒钟后又刷新他/她的浏览器。现在HasSet仍然包含2个用户,并且任务永远不会启动。我会怎么去呢? – ShaneKm 2013-03-04 18:05:49

+0

什么是确切的repro步骤? – davidfowl 2013-03-04 18:13:54

+0

看起来像这帮助:GlobalHost.Configuration.DisconnectTimeout。我在我的global.asax中将其设置为1秒。谢谢 – ShaneKm 2013-03-06 10:47:24

0

我刚刚遇到过这种情况。 onDisconnect并不总是被解雇。我的解决方案是偶尔查看用户是否仍然连接。

Public Sub checkconnections() 
    For Each s In users 
     Clients.User(s).areYouThere() 
    Next 
    users = New List(Of String) 
    System.Threading.Thread.Sleep(5000) 
    checkconnections() 
End Sub 
Public Sub imHere() 
    Dim id = GetClientId() 
    If Not users.Contains(id) Then 
     users.Add(id) 
    End If 
    Clients.All.sendCount(count) 
End Sub 

所以每5秒枢纽发送到用户列表中的所有客户端,然后清除列表。

如果客户端收到'areYouThere'消息,它会回复'imHere',然后将其添加到列表中。

希望这会有所帮助。