2015-01-01 40 views
2

我正在嘗試構建一個聊天應用程序,用戶ID由其自動生成的signalR連接ID表示。在頁面刷新時,連接標識在實例化新連接時發生變化。有沒有辦法在瀏覽器會話結束之前(即直到他在客戶端結束他的會話)持久化用戶的連接ID狀態。如何堅持SignalR連接ID

任何指南或文檔?這真的會有所幫助。

我是信號發生器的新手。所以試圖知道搜索谷歌的許多事情。從這個URL我得到了一個類似的片段http://kevgriffin.com/maintaining-signalr-connectionids-across-page-instances/

他們說這是可能的。問題是如果我們刷新頁面,信號員經常創建一個新的連接ID。我想防止這個,但如何.......

此代碼段。

public class MyConnectionFactory : IConnectionIdFactory 
    { 
     public string CreateConnectionId(IRequest request) 
     { 
      if (request.Cookies["srconnectionid"] != null) 
      { 
       return request.Cookies["srconnectionid"]; 
      } 

      return Guid.NewGuid().ToString(); 
     } 
    } 

$.connection.hub.start().done(function() { 
     alert("Connected!"); 
     var myClientId = $.connection.hub.id; 
     setCookie("srconnectionid", myClientId); 
    }); 

    function setCookie(cName, value, exdays) { 
     var exdate = new Date(); 
     exdate.setDate(exdate.getDate() + exdays); 
     var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString()); 
     document.cookie = cName + "=" + c_value; 
    } 

我的疑問是它在所有signalr版本中工作嗎?如果沒有,那麼如何在新版本中處理它,特別是在頁面被刷新時不生成新的連接ID。尋找建議。

如果我們使用持久連接類而不是集線器,那麼會發生什麼.....在這種情況下,如果我們在客戶端刷新頁面,連接ID將會持續存在?請指導。 謝謝

回答

2

SignalR允許您通過他們的IPrincipal.Identity.Name發送消息給用戶。只需使用Clients.User(userName)而不是Clients.Client(connectionId)

如果由於某種原因無法使用他們的用戶地址IPrincipal.Identity.Name可以創建您自己的IUserIdProvider。這是SignalR> = 1.0.0中不再存在的IConnectionIdFactory的替代品。

等效IUserIdProvider應該是這樣的:

public class MyConnectionFactory : IUserIdProvider 
{ 
    public string GetUserId(IRequest request) 
    { 
     if (request.Cookies["srconnectionid"] != null) 
     { 
      return request.Cookies["srconnectionid"]; 
     } 

     return Guid.NewGuid().ToString(); 
    } 
} 

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var idProvider = new MyConnectionFactory(); 
     GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider),() => idProvider); 

     app.MapSignalR(); 
    } 
} 

public class MyHub : Hub 
{ 
    public Task Send(string userName, string message) 
    { 
     return Clients.User(userName).receive(message); 
    } 
} 

這將是非常無聊的惡搞給這個MyConnectionFactory用戶。您可以通過使用HMAC使其更安全。

理想情況下,您只需使用default IUserIdProvider即可從IRequest.User.Identity.Name中檢索用戶標識。

+0

感謝您的回答。我需要使用什麼信號器版本來運行你的代碼。我正在使用signalr和VS2010 IDE。所以告訴我你的代碼適用於VS2010版本嗎? – Mou

+0

Clients.User(userName)和 Clients.Client(connectionId)方法有什麼區別。用戶名可能不是唯一的,但connectionId始終是唯一的。所以如果userName不唯一會發生什麼?請指導。謝謝 – Mou

+0

在SignalR 1.0.0中刪除了IConnectionIdFactory。 SignalR 2.0.0中引入了IUserIdProvider。你的VS版本應該不重要。你是正確的,可以是多個SignalR連接具有相同的用戶名。例如,同一用戶可能會在多個瀏覽器選項卡中打開SignalR應用程序。在這種情況下,屬於具有userName的用戶的每個連接都將使用Clients.User(userName)接收發送給該用戶的消息。 – halter73

0

用戶ID提供程序不起作用,因爲連接ID不是來自它。我實施了一個解決方案(https://weblogs.asp.net/ricardoperes/persisting-signalr-connections-across-page-reloads),該解決方案使用存儲在會話存儲中的僞會話標識。然後將每個SignalR連接標識映射到此僞會話標識。

+0

請不要發表(幾乎)相同的答案多個問題。如果它們是重複的,那麼請使用您的密切投票。如果他們不是,那麼嘗試針對這些特定問題定製你的答案。此外,請不要發佈僅鏈接的答案。您可以在此提供(部分)代碼並使用鏈接以供參考。 –