从同一服务器上的 Windows 服务发送 运行 在 ASP.NET MVC 应用程序中的 SignalR 广播

Sending SignalR Broadcasts that is running within ASP.NET MVC Application from a Windows Service on the same server

我有一个 ASP.NET 网站,它使用 SignalR 集线器向网站用户发送消息。

我有在我的业务层中调用集线器的代码,我使用依赖注入将集线器的实例从我的 ASP.NET 应用程序注入到我的业务层。

我遇到的问题是,当我开始在 Windows 服务中使用我的业务层时,我不知道如何获取集线器的实例。

是否可以从服务器 'hook' 进入我现有的 SignalR 集线器,即 运行 在我的 ASP.NET 应用程序中并从我的 Windows 服务发送广播?

我意识到我可以使用以下代码在我的 windows 服务中作为客户端连接,但这是错误的方法,我想发送广播 from 服务器...

// This code enables a client connection
var connection = new HubConnection("http://localhost:3537/");
IHubProxy myHub = connection.CreateHubProxy("NotificationHub");

connection.Start().Wait(); 

myHub.Invoke("setNotificationCount", "5");

编辑: 所以根据我们在这里的讨论是我对问题的理解:

问题: 现有项目可以访问 SignalR 客户端,并且该项目需要在与具有这些客户端的项目相同的服务器上响应 windows 服务事件 运行。

我的解决方案: 我会构建或使用一个 webAPI 项目作为服务和服务器项目之间的桥梁。该服务可以调用 webAPI 方法,这些方法依次访问您的业务级逻辑,然后根据需要更新 SignalR 客户端。这也有利于使用 Microsoft 提供的内置保护(即任何身份验证方案:表单、windows 等)。


this 教程解释的方式是,为了向客户端广播,您首先需要获取对所有已连接客户端的引用。

GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients) 是否有关于如何 return 客户列表的示例

从那里你需要做类似的事情(再次使用他们的例子):Clients.All.SomeClientMethod(string aParameter)

您的中心托管在 ASP.NET 应用程序中。所以不,你无法直接从 windows 服务广播...而不使用 SignalR 的横向扩展功能...

解决方案 1(不使用横向扩展 - 首选)

Windows 服务作为客户端连接到 APS.NET 应用程序 (hub1) 内的集线器 运行ning 并调用特殊的集线器方法,该方法向所有客户端广播消息。 OFC 这种方法可以被普通(浏览器)客户端滥用。为了消除这种情况,你可以在ASP.NET 应用程序中创建另一个集线器(hub2),将方法放在此处并使用GlobalHost.ConnectionManager.GetHubContext<hub1>() 广播到连接到hub1 的所有客户端。 Hub2 可以受到保护 by authorization 因此只有 Windows 服务可以使用它。 由于您已经在使用 DI 容器并将集线器注入业务逻辑,因此定义通用接口 (INotificationService) 并创建两个不同的实现应该很容易——第一个将在 ASP.NET 应用程序中使用(使用 Hub1 进行实际通知) ),第二个将在 Windows 服务内部使用,并使用 Hub2 将通知传递给 ASP.NET 应用程序。从BL的角度来看,都是一样的...

OFC for Win Service -> ASP.NET通信,你可以使用任何其他通信技术,如MVC或WebAPI(如@Pseudonym建议的),而不仅仅是SignalR

解决方案 2

如果出于某种原因这不是您的解决方案,还有另一种想法。 我认为 SignalR scaleout feature 可以在这里(错误)使用。只需将 hub1 both 托管在 ASP.NET and Windows 服务中(使用不同的 URL 和端口!) .即使客户端将仅直接连接到 ASP.NET 应用程序,代码 运行ning 在 Windows 服务中仍然能够向它们广播消息(消息被传递到 scaleout 消息总线,然后到 ASP.NET 应用程序,然后是客户端)。

使用横向扩展(需要 SQL Server\Redis 或任何其他 SignalR 背板 + 延迟等)事情会更复杂,您可能想要锁定 Windows 服务中心,以便客户端无法直接连接到它和 运行 hub1 方法(我不知道该怎么做 - 一个想法是使用另一个集线器实现但具有相同的名称(HubNameAttribute)和空方法+授权所以没有人可以连接到它)。 无论如何,这更麻烦,你应该有充分的理由走这条路......