从 MVC 中的控制器 class 获取客户端的连接 ID

Getting Connection Id of the client from a Controller class in MVC

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

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

谁能给点意见?

在这篇文章中_ How to obtain connection ID of signalR client on the server side?

_第一个答案建议您让集线器调用外部方法。

我知道我们保留一个字典的设计,该字典将每个 userId 映射到多个设备的多个 ConnectionId。

但假设有一个 UserController,它具有登录和注销操作。如果我能得到刚刚登录的用户的 connectionId 会更容易。然后我会简单地从 DbContext 中得到它的 userID 并将它存储在前面提到的 Dictionary 中,稍后 Hub 可以使用它。

您可以在客户端的 JavaScript 中使用 $.connection.hub.id 并在 SignalR 中心 (see here) 中使用 Context.connectionId 来获取用户的连接 ID。

然后你可以用它做任何你想做的事,你可以 post 它从客户端通过 AJAX 到控制器,或者从服务器端到你的客户端从你的 SignalR 集线器。

如果您需要从控制器中检索尚未以某种形式(会话、数据库)保存的 SignalR 连接 ID - 这对我来说听起来像是一种代码味道。

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

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

就将您的连接 ID 映射到登录用户而言,只要您的用户已经登录,当您建立与 SignalR 集线器的连接时,这将作为默认功能执行。

在集线器内,您可以获得呼叫集线器的用户的 ID,并return通过他们的用户名或用户 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();
    }
}