2013-03-04 21 views
5

Tôi cần kiểm tra xem liệu một người dùng cụ thể nào vẫn được kết nối.người dùng được kết nối theo dõi tín hiệuR

Tôi đã HashSet sau đó theo dõi người sử dụng:

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

Vì vậy, về ngắt kết nối:

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

và trên kết nối:

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(); 
    } 

Bây giờ, vấn đề nảy sinh khi người dùng chỉ cần đóng cửa sổ trình duyệt của mình. Không có cách nào để tôi biết nếu anh ta/cô ấy bị ngắt kết nối.

Vì vậy, dựa trên một số câu hỏi here, tôi sẽ gọi cho từng khách hàng và nhận phản hồi. Tôi không chắc chắn làm thế nào để làm điều đó.

Tôi đoán tôi sẽ có điều này:

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

NHƯNG làm thế nào để tôi nhận được một phản ứng trở lại hình thành khách hàng?

EDIT: bước được thực hiện:

tôi cần chính xác số lượng người sử dụng kết nối vì Nếu có ít nhất một người dùng kết nối với tôi cần phải bắt đầu một nhiệm vụ. Và tôi muốn đảm bảo rằng chỉ có 1 nhiệm vụ đang chạy cho tất cả người dùng được kết nối < 2 (bắt đầu một nhiệm vụ). giả sử một tình huống như thế này: 2 người dùng xem một trang đang sử dụng signalR. HashSet bây giờ chứa 2 id và một nhiệm vụ đang chạy. Một đóng trình duyệt của anh/cô ấy và sau một vài giây và một trình duyệt khác làm mới/của cô ấy/cô ấy. Bây giờ, cái đầu tiên (cái đóng trình duyệt của anh ta không thực thi phương thức OnDisconnected nên HashSet vẫn có ConnectionId của anh ta, và cái mà "refreshed" đã thực hiện OnDisonnected và sau đó OnConnected đã thêm connectionId của nó vào HashSet. của việc có duy nhất 1 ConnectionId trong một HashSet và bắt đầu một nhiệm vụ, HashSet chứa 2 (cũ-không kết nối được nữa và một trong đó chỉ làm mới/trình duyệt của mình), và các nhiệm vụ không bao giờ bị bắt đầu một lần nữa.

nhờ

Trả lời

6

Với SignalR 1.0, OnDisconnected phải luôn luôn kích hoạt, ngay cả khi người dùng đóng cửa sổ của họ (ngoại lệ cho điều này nếu máy chủ khởi động lại)

OnDisconnected có thể không kích hoạt ngay lập tức, vì nếu máy khách không "hủy bỏ" kết nối được coi là "không sạch" vì có khả năng máy khách có thể thử và kết nối lại (và nếu bạn kết nối lại, bạn chưa ngắt kết nối theo ngữ nghĩa của SignalR) .

Theo mặc định, sẽ mất khoảng 30 giây để máy chủ gọi OnDisconnected cho ngắt kết nối "không sạch". Điều này có thể được cấu hình lại thông qua GlobalHost.Configuration.DisconnectTimeout.

+0

điều là tôi cần số lượng người dùng chính xác được kết nối vì nếu có ít nhất một người dùng được kết nối, tôi cần phải bắt đầu một tác vụ. Và tôi muốn đảm bảo rằng chỉ có 1 tác vụ đang chạy cho tất cả người dùng được kết nối <2 (bắt đầu một nhiệm vụ). giả sử tình huống này: 2 người dùng xem một trang đang sử dụng signalR. HashSet hiện chứa 2 id. Một đóng trình duyệt của anh/cô ấy và sau một vài giây, một trình duyệt khác sẽ làm mới/của cô ấy/cô ấy. Bây giờ HasSet vẫn chứa 2 người dùng và một nhiệm vụ sẽ không bao giờ bắt đầu. Làm thế nào tôi sẽ đi về nó ?? – ShaneKm

+0

Các bước repro chính xác là gì? – davidfowl

+0

trông như thế này đã giúp: GlobalHost.Configuration.DisconnectTimeout. Tôi đặt nó 1 giây trong global.asax của tôi. cảm ơn – ShaneKm

0

Tôi vừa gặp phải tình huống tương tự này. OnDisconnect không phải lúc nào cũng được kích hoạt. Giải pháp của tôi là thỉnh thoảng thăm dò ý kiến ​​của người dùng để xem họ có còn kết nối không.

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 

cứ sau 5 giây trung tâm gửi cho tất cả khách hàng trong danh sách người dùng sau đó xóa danh sách.

Nếu khách hàng nhận được thông báo 'areYouThere', ứng dụng sẽ trả lời bằng 'imHere' mà sau đó sẽ được thêm vào danh sách.

Hy vọng điều này sẽ hữu ích.