如何对集线器进行 SignalR 外部引用而不执行循环引用?

How do I make a SignalR external reference to hub and not perform circular reference?

所以,我正在尝试创建一个示例,其中包含以下 components/features:

Github Project

我可以让任务排队并执行,但我很难弄清楚如何通知客户(目前都是,直到我让它运行良好)task/job已完成。

我当前的问题是我希望 SignalR 集线器位于 "core" 库 SampleCore, but I don't see how to "register it" when starting the webapp SampleWeb. One way I've gotten around that is to create a hub class NotificationHubProxy 中,它继承了实际的集线器并且适用于简单的东西(从一个客户端发送消息到全部)。

NotifyTaskComplete 中,我相信我可以获取集线器上下文,然后像这样发送消息:

private void NotifyTaskComplete(int taskId)
    {
        try
        {
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
            if (hubContext != null)
            {
                hubContext.Clients.All.sendMessage(string.Format("Task {0} completed.", taskId));
            }
        }
        catch (Exception ex)
        {
        }
    }

但是,如果 NotificationHubProxy 是 class,我不能这样做,因为它是 SampleWeb 库的一部分并且从 SampleCore 引用它会导致循环引用。

我知道主要问题是外部组件中的集线器,但我终其一生都找不到使用 SignalR 或 MVC5 或以这种特定方式设置的相关示例。

有什么想法吗?

因此,解决方案是执行以下两件事:

  1. 我必须使用 SampleCore 程序集中的 SignalR .NET 客户端创建一个 HubConnection,为 "NotificationHub" 创建一个 HubProxy 并使用它来调用 "SendMessage" 方法- 像这样:

    private void NotifyTaskComplete(string hostUrl, int taskId)
    {
        var hubConnection = new HubConnection(hostUrl);
        var hub = hubConnection.CreateHubProxy("NotificationHub");
        hubConnection.Start().Wait();
        hub.Invoke("SendMessage", taskId.ToString()).Wait();
    }
    

但是,作为创建 HubConnection 的一部分 - 我需要知道 OWIN 实例的 url。我决定将那个参数传递给任务,像这样检索它:

private string GetHostAddress()
{
    var request = this.HttpContext.Request;
    return string.Format("{0}://{1}", request.Url.Scheme, request.Url.Authority);
}
  1. 将集线器置于外部程序集中的解决方案是需要在设置 SignalR 路由之前加载程序集,如下所示:

    AppDomain.CurrentDomain.Load(typeof(SampleCore.NotificationHub).Assembly.FullName);
    app.MapSignalR();
    

这部分的解决方案来自 here