从MVC控制器添加SignalR Hub组

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

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

我想从我的MVC控制器中调用这个Hub方法 . 我的方法目前看起来像这样:

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

        return View();
    }
}

但是,控制器中的代码不会调用hub方法 . 我可以更改什么才能成功调用hub方法?

回答(1)

2 years ago

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

SignalR连接仅适用于客户端上的一个"page view" . 换句话说,如果我去 /chat/rooms/1 ,我得到一个 ConnectionId ,然后如果我导航到 /chat/rooms/2 ,我得到一个不同的 ConnectionId . 因此, base.Context.ConnectionId 基本上没有尝试在这里使用它 .

这给你留下了两个选择 .

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

  • 这基本上是一回事,但是如果你使用SPA框架让你在视图之间保持SignalR连接,那就行了 . 当然,这是一个非常重大的变化 .

我假设您的操作 AddEmail 实际上是一个页面,我根据它推断出它返回一个 ViewResult . 如果使用AJAX调用它,您可以将 ConnectionId 附加为查询参数,所有这些都没有实际意义 .