0

因此,我正在尝试创建一个包含以下组件/功能的示例:

  • 从 Windows 服务自托管的 hangfire 服务器 OWIN
  • 作业完成时的 SignalR 通知

Github 项目

我可以将任务排队并执行,但我很难弄清楚如何在任务/作业完成时通知客户(目前都是,直到我让它正常工作)。

我当前的问题是我希望 SignalR 集线器位于“核心”库SampleCore中,但在启动 webapp SampleWeb时我看不到如何“注册” 。我解决这个问题的一种方法是创建一个集线器类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 是被使用的类,因为它是 SampleWeb 库的一部分并且从 SampleCore 引用它会导致循环引用,我不能这样做。

我知道主要问题是外部程序集中的集线器,但我一辈子都找不到使用 SignalR 或 MVC5 或以这种特殊方式设置的相关示例。

有任何想法吗?

4

1 回答 1

2

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

  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();
    

这部分的解决方案来自这里

于 2015-03-24T17:28:10.537 回答