2013-03-04 68 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',然後將其添加到列表中。

希望這會有所幫助。