Asp.net mvc 从MVC中的控制器类获取客户端的连接Id

Asp.net mvc 从MVC中的控制器类获取客户端的连接Id,asp.net-mvc,client-server,signalr,Asp.net Mvc,Client Server,Signalr,我正在使用signalR在MVC中构建一个聊天应用程序。我知道如何从中心获取客户端的ConnectionID。 但是有可能从控制器获得相同的connectionID吗 我尝试使用HttpContext和OwinContext,但从几个属性中找不到ConnectionId属性。甚至在HttpContext的请求属性中也没有 有人能告诉我一些想法吗 在这篇文章里 _第一个答案建议您让中心调用外部方法 我知道有一种设计,我们保存一个字典,将每个用户ID映射到多个设备的多个ConnectionID 但是

我正在使用signalR在MVC中构建一个聊天应用程序。我知道如何从中心获取客户端的ConnectionID。 但是有可能从控制器获得相同的connectionID吗

我尝试使用HttpContext和OwinContext,但从几个属性中找不到ConnectionId属性。甚至在HttpContext的请求属性中也没有

有人能告诉我一些想法吗

在这篇文章里

_第一个答案建议您让中心调用外部方法

我知道有一种设计,我们保存一个字典,将每个用户ID映射到多个设备的多个ConnectionID


但是假设有一个UserController,它有一个登录和注销操作。如果我能得到刚刚登录的用户的connectionId,那就容易多了。然后,我只需从DbContext中获取其用户id,并将其存储在前面提到的字典中,该字典稍后可由中心使用。

您可以在客户端的JavaScript中使用
$.connection.Hub.id
,并在SignalR Hub()中使用
Context.connectionId
来获取用户的连接id

然后,您可以使用它做任何您想做的事情,您可以通过AJAX从客户端将它发布到控制器,或者从服务器端从signarhub发布到您的客户端

如果您需要从控制器中检索尚未以某种形式(会话、数据库)持久化的信号器连接ID,这听起来像是代码气味

您应该在您的信号中心内执行您需要执行的任何操作。无论是某种处理,还是将客户端ID发送到数据库供控制器稍后使用

如果问题是您想要执行的代码已经存在于您的控制器中,并且您想要使用该代码,并且您不希望它存在于两个地方,那么您应该将该代码移动到服务层(业务层),并将其作为依赖项添加到控制器和信号集线器中

就将连接ID映射到已登录用户而言,只要用户已登录,在建立到信号集线器的连接时,这将作为默认功能执行

在集线器中,您可以获取呼叫集线器的用户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();
    }
}

您可以在客户端获取它,然后将值发送到控制器。这可以接受吗?如果我想在“index.cshtml”页面登录,可能会重复:的内容。然后我转到“chat.cshtml”页面开始聊天。现在,在这种情况下,我如何将我的UserID映射到我的connectionID?我的想法是,由于登录是由控制器完成的,因此在包含控制器(例如UserController)的登录操作中添加此条目将是有意义的。当您在
chat.cshtml
上建立连接时,您的信号器连接将自动分配给此帖子中的用户idies()我知道IUserId提供者会给我用户ID。我正在尝试使用该帖子中的第二种方法(即使用内存存储)来实现,假设我对信息的存储有更多的控制权。当页面与您的SignalR hub建立连接时,用户的连接ID将添加到内存集合中,而不是当您的用户通过控制器登录时。SignalR连接是使用JavaScript通过HTTP请求建立到集线器的,在集线器上生成连接ID。我很想直接使用SignalR,因为它是开箱即用的,并确定是否需要使用内存中的东西。SignalR与ASP.NET Identity很好地集成,无需在内存中保留连接,除非有特定要求。如果您有一个聊天页面,您只想向打开聊天页面的用户发送消息,您可以使用他们的
userid
轻松完成此操作,即使他们打开了多个页面,您也不需要担心连接ID。