从 MVC 控制器添加 SignalR Hub 组

Adding a SignalR Hub Group from an MVC Controller

我有一个带有非静态方法的 SignalR Hub,该方法会根据在表单中输入的电子邮件地址创建一个新组:

public class EmailHub : Hub
{
    public void AddEmail(string email)
    {
        base.Groups.Add(base.Context.ConnectionId, email);
    }
}

我想从我的 MVC 控制器调用这个集线器方法。我的方法目前看起来像这样:

public class MyController : Controller
{
    public ActionResult AddEmail(string email)
    {
        var hub = GlobalHost.ConnectionManager.GetHubContext<EmailHub>();
        hub.Clients.All.AddEmail(email);

        return View();
    }
}

但是controller中的代码并没有调用hub方法。我可以更改什么才能成功调用集线器方法?

您必须将 ConnectionId 作为参数传递,并且在 SignalR 已连接之前您无法获取它。

客户端上只有一个 "page view" 存在 SignalR 连接。换句话说,如果我去 /chat/rooms/1,我得到一个 ConnectionId,然后如果我导航到 /chat/rooms/2,我得到一个 different ConnectionId。因此,当您尝试在此处使用它时,base.Context.ConnectionId 基本上不存在。

你有两个选择。

  1. 在每个页面上连接 SignalR 后订阅更新。在这种情况下,您将提交一个典型的 AddEmail 请求,然后在 JavaScript 中 View() 加载后,您加载 SignalR,连接,然后提交 hub.server.addEmail(email)。这是 SignalR 中的标准方法。

  2. 这本质上是同一件事,但如果您使用的 SPA 框架可以让您在视图之间保持 SignalR 连接,那将是可行的。当然,这是一个非常重要的变化。

我所有这些都是基于这样的假设,即您的操作 AddEmail 实际上是一个页面,我从中推断出它 returns 和 ViewResult。如果用 AJAX 调用,您可以将 ConnectionId 作为查询参数附加,所有这些都没有实际意义。