2015-11-02 50 views
3

我正在使用signalR在MVC中構建一個聊天應用程序。我知道如何從Hub獲取客戶端的ConnectionID。 但是有可能從控制器獲得相同的connectionID?從MVC中的Controller類獲取客戶端的連接Id

我試過使用HttpContext和OwinContext,但從幾個屬性中我找不到ConnectionId屬性。甚至不在HttpContext的Request屬性中。

任何人都可以提供任何想法嗎?

在這種post_ How to obtain connection ID of signalR client on the server side?

_The第一個答案建議您有集線器調用外部方法。

我知道我們在哪裏設計一個字典,將每個userId映射到幾個設備的多個ConnectionIds。

但讓我們說有一個UserController有一個LogIn和LogOut行動。如果我可以獲得剛剛登錄的用戶的connectionId,那麼會更容易。然後,我只需從DbContext獲取其用戶標識,並將它存儲爲之前提到的Dictionary,稍後可由Hub使用它。

+1

您可以在客戶端獲取它,然後將值發送給控制器。這可以接受嗎? –

+1

可能的重複:http://stackoverflow.com/questions/20908620/how-to-obtain-connection-id-of-signalr-client-on-the-server-side – Nikolay

回答

1

您可以在客戶端的JavaScript中使用$.connection.hub.id,在SignalR集線器中使用Context.connectionIdsee here)以獲取用戶的連接ID。

然後,您可以隨心所欲地做任何事情,您可以從客戶端通過AJAX將其從SignalR集線器發佈到控制器,或從服務器端發佈到客戶端。

如果您需要從控制器中檢索尚未以某種形式(會話,數據庫)持久保留的SignalR連接標識符 - 這聽起來像是一種代碼味道。

您應該在SignalR集線器內執行任何您需要做的事情。無論是進行某些處理,還是將您的客戶端ID發送到數據庫以供控制器稍後使用。

如果問題是您想要執行的代碼已經存在於您的Controller中,並且您想使用該代碼而您不希望它存在於兩個地方,則應該將此代碼移至服務層(業務層)並將其作爲依賴添加到您的Controller和SignalR集線器。

在您的網絡連接ID映射到登錄的用戶,這是默認的功能,當你建立一個SignalR集線器的連接,只要你的用戶已經登錄在執行方面。

在中樞中,您可以獲得呼叫您的集線器的用戶的ID,並通過其用戶名或用戶ID將消息返回給他們:

public MyHub : Hub 
{ 
    public void FirstMethod() 
    { 
     // Invoke method to the current caller to the hub 
     Clients.Client(connectionId).clientMethod(); 
    } 

    public void SecondMethod() 
    { 
     // Get user id of the person making the call 
     var userId = this.User.Identity.GetUserId(); 

     // Invoke method on the client side 
     Clients.User(userId).clientMethod(); 
    } 
} 
+0

如果我想登錄在「 index.cshtml「頁面。然後我轉到「chat.cshtml」頁面開始聊天。現在在這種情況下,我怎樣才能將我的UserID映射到我的connectionID? 我的想法是因爲Login是由控制器完成的,所以在包含控制器(例如UserController)的Login Action中添加會很有意義。 –

+0

當您通過「聊天」建立連接時。cshtml',你的SignalR連接自動分配給用戶ID爲 – Luke

+0

yes從這篇文章(http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections)我瞭解到IUserId Provider會給我UserId。我試圖在該文章中使用第二種方法(即使用內存存儲),假設我將對信息的存儲有更多的控制。 –