2013-11-27 113 views
3

嗨,我正在開發一個聊天應用程序以及我的應用程序中的一些其他頁面。一旦我登錄,我正在維護用戶的會話。我的主要目的是當用戶連接到服務器時,用戶應該會收到通知。SignalR:如何停止創建新的連接頁面刷新

我面臨的問題是每當我導航到我的應用程序中的其他頁面時,連接都會丟失。如何停止此行爲並繼續連接,直到用戶註銷。

我在ASP.NET MVC4項目中使用SignalR 2.0,有什麼幫助?

+0

你應該保持用戶在數據庫或其他地方的狀態。並應在每次用戶註銷時通知其他用戶,而不是在signalR關閉連接時通知其他用戶 – Patel

+0

signalR在每次重新載入頁面時關閉連接,如何阻止此行爲? @Patel –

+0

什麼是完美的是基於要求@Patel的主觀,從我的要求來看它的怪異。 –

回答

4

每個連接在用戶在給定頁面上花費的時間內只有一個生命週期。當他們導航到另一個頁面時,建立一個新的連接。另外,如果用戶打開多個選項卡或瀏覽器窗口,則它們將具有多個連接ID。我不認爲你想嘗試持續連接Id超出預期的生命週期。

在我工作的類似場景中,我們存儲connectionIds OnConnect並將它們刪除OnDisconnect。當需要將消息發送給給定的用戶時,我們將其發送給它們的所有connectionIds。這確保了郵件將被傳送到所有標籤頁/窗口。

EDIT 1以下是響應@ SAURABH的評論:

考慮樞紐的範圍是什麼,你的其他類和客戶端。 Hub是爲了方便瀏覽器和服務器之間的通信。儘管可以在樞紐內做很多工作,但我認爲最好的做法是把公共場所以外的大部分範圍移到其他地方。

客戶端知道它只是重新加載了一個頁面,因此它是決定這是重新連接事件的良好候選者。

_chatHub.server.reJoinRooms(); 

然後Hub可以通過UserId而不是ConnectionId查詢用戶的房間。

public Task ReJoinRooms() 
{ 
// get the user's rooms from your repository 
// optionally get the user's connectionIds from your repository 
// Clients.Caller.onJoinRooms(rooms); 
// or Clients.Clients(_connectionIds).onJoinRooms(rooms); 
} 

然後客戶可以決定是否要採取行動:

$chatModule.client.onJoinRooms = function (rooms) { 
    for (var i in rooms) { 
      var _room = rooms[i]; 
      // if I'm not already in this room, add it to my rooms 
      console.log('joining room', _room) 
     } 
} 

你可以皮膚這麼多不同的方式。客戶可以擁有記憶室的範圍,而不是服務器端存儲庫。

編輯2

如果用戶所屬的日益增加的基團/房間的數目,上面的例子可以不擴展得非常好。

在這種情況下,每個用戶可以加入個人提要(即加入一個以用戶的GUID命名的提要)。我們會跟蹤與某個組關聯的每個用戶。當郵件發送到該羣組時,我們會迭代這些用戶並向每個郵件發佈一條消息。

+0

我同意,我現在也遵循同樣的策略,但問題是我顯示的是連接到服務器的用戶,所以當用戶導航到其他頁面時,他不再顯示在線。只要他使用的是應用程序,而不是基於頁面,我想要使連接持久。 @andes –

+1

啊,對。您可以在會話期間保持用戶的狀態,而不是狀態是其connectionId的功能。對於轉換,例如重新加入房間,您可以包含一個bool參數以指示用戶正在「重新連接」,在這種情況下,您可以吞下將會爲此類事件推送的普通消息。 – andes

+0

如何識別同一用戶正在重新連接,因爲連接ID是GUID,您能否提供一些代碼片段。這將有助於@andes –