我有一个ASP.NET网站,它使用SignalR集线器向网站用户发送消息。
我有调用业务层中的集线器的代码,并使用依赖注入将集线器的实例从我的ASP.NET应用程序注入到我的业务层。
我遇到的问题是,当我在Windows服务中使用我的业务层时,我不知道如何获取集线器的实例。
是否可以勾选'从我的ASP.NET应用程序中运行的服务器的现有SignalR集线器并从我的Windows服务发送广播?
我意识到我可以使用以下代码在我的Windows服务中作为客户端连接,但这是错误的方式,我想从服务器发送广播 ...
// 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");
答案 0 :(得分:1)
编辑:因此,基于我们的讨论,我对此问题的理解是:
<强>问题:强> 有一个现有项目可以访问SignalR客户端,该项目需要响应与这些客户端项目在同一服务器上运行的Windows服务事件。
我的解决方案: 我会构建或使用webAPI项目来充当服务和服务器项目之间的过程。该服务可以调用webAPI方法,然后访问您的业务级逻辑,然后根据需要更新SignalR客户端。这还有一个优点,即可以使用Microsoft提供的内置保护(即任何身份验证方案:表单,窗口等)。
this教程解释的方式是,为了向客户端广播,首先需要引用所有连接的客户端。
GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients)
有关于如何返回客户列表的示例
从那里你需要做一些事情(再次使用他们的例子):Clients.All.SomeClientMethod(string aParameter)
答案 1 :(得分:1)
您的集线器托管在ASP.NET应用程序中。所以不,没有办法直接从Windows服务广播......没有使用SignalR的横向扩展功能......
解决方案1(不使用横向扩展 - 首选):
Windows服务作为客户端连接到在APS.NET应用程序(hub1)内运行的集线器,并调用特殊的集线器方法,该方法向所有客户端广播消息。 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 - &gt; ASP.NET通信,你可以使用任何其他通信技术,如MVC或WebAPI(如@Pseudonym建议),而不仅仅是SignalR
解决方案2
如果由于某种原因这不是你的解决方案,还有另外一个想法。 我认为SignalR scaleout feature可以(误)在这里使用。只需在ASP.NET 和 Windows服务(具有不同的URL和端口!)中托管您的hub1 两者。即使客户端只能直接连接到ASP.NET应用程序,Windows服务中运行的代码仍然可以向它们广播消息(消息传递到scaleout消息总线,然后传递到ASP.NET应用程序,然后传递给客户端)。
使用横向扩展(需要SQL Server \ Redis或任何其他SignalR背板+延迟等等)并且您可能希望锁定Windows服务集线器以使客户端无法直接连接到它并运行hub1方法(i&# 39;我不知道该怎么做 - 一个想法是使用另一个集线器实现,但使用相同的名称(HubNameAttribute
)和空方法+授权,所以没有人可以连接到它。
无论如何这更麻烦,你应该有充分的理由走这条路......