首页 > 解决方案 > SignalR:GetHubContext 不调用客户端方法,但直接引用集线器会

问题描述

上周我在处理 SignalR (v 2.4.1) 集线器时遇到了一个令人不安的问题,尽管通过文档做了足够多的工作,但我无法在不破解它的情况下广播消息。对于一些额外的上下文,这是一个附加到 Windows 服务的自托管 (Owin) 集线器。

MSDN 文档和运行时错误(不支持使用不是由 HubPipeline 创建的 Hub 实例)表明我们应该通过调用来获取集线器上下文GlobalHost.ConnectionManager.GetHubContext<ThisTypeOfHub>(),此时我们可以调用客户端。(https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#callfromoutsidehub

当我最初设置呼叫客户时,我是这样做的:

public void OnDisplayMessage(string message)
{
  var hub = GlobalHost.ConnectionManager.GetHubContext<ThisTypeOfHub>();
  hub.Clients.All.BroadcastToClient(message);
}

然而,包含该方法并连接到 signalR 的浏览器从未被调用。客户端可以调用服务端方法,甚至服务端方法也会发出一个客户端响应的回调,但是当从集线器外部调用时,集线器上下文永远不会调用客户端方法。最后,我直接在 IoC 容器中带回了 hub 引用,并使用它调用客户端,如下所示。

public class LogicWithUI : Logic
{
  Hub hub;

  public LogicWithUI(IDependencyInjectionContainer container) 
  {
    this.hub = container.Resolve<ThisTypeOfHub>();  // ThisTypeOfHub inherits from Hub
  }

  public class OnDisplayMessage(string message)
  {
    try 
    {
      this.hub.Clients.All.DisplayMessage(string);
    }
    catch (Exception)
    {
       //do nothing, no webpage has connected yet
    }
  }
}

这样它最终可以正常工作(您可以看到发生错误时放置在那里的catch - 仅当还没有网页连接到它时),但这没有意义。

  1. 什么会导致从集线器外部调用的 HubContext 实际上没有广播该方法?
  2. 为什么只有在没有连接客户端时才会抛出不受支持的错误?
  3. 我在这里忽略了任何明显的错误吗?

这里的主要目标是拥有一个功能正常的产品,但我也想以正确/记录的方式来做。当这种方式不起作用时,这有点令人困惑。

我也明白我可能遗漏了有关 SignalR 配置的一些重要细节,我可以回答任何后续问题,但想从基本解释开始。

标签: c#dependency-injectionunity-containersignalr-hub

解决方案


推荐阅读