在后台服务中宿主 ASP.NET Core SignalRHost ASP.NET Core SignalR in background services
本文提供以下内容的指导:
- 使用托管 ASP.NET Core 的后台工作进程承载 SignalR 中心。
- 从 .NET Core BackgroundService中将消息发送到已连接的客户端。
在后台工作进程的上下文中托管 ASP.NET Core SignalR 中心与在 ASP.NET Core web 应用中托管集线器完全相同。在 方法中,调用 services.AddSignalR
会将所需的服务添加到 ASP.NET Core 依赖关系注入(DI)层以支持 SignalR。在 Startup.Configure
中,MapHub
方法在 UseEndpoints
回调中调用,以连接 ASP.NET Core 请求管道中的中心终结点。
在后台工作进程的上下文中托管 ASP.NET Core SignalR 中心与在 ASP.NET Core web 应用中托管集线器完全相同。在 Startup.ConfigureServices
方法中,调用 services.AddSignalR
会将所需的服务添加到 ASP.NET Core 依赖关系注入(DI)层以支持 SignalR。在 Startup.Configure
中,调用 UseSignalR
方法连接 ASP.NET Core 请求管道中的中心终结点。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddHostedService<Worker>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSignalR((routes) =>
{
routes.MapHub<ClockHub>("/hubs/clock");
});
}
}
在前面的示例中,ClockHub
类实现了 Hub<T>
类,以创建强类型化的中心。已在 Startup
类中配置 ClockHub
,以响应终结点 /hubs/clock
的请求。
备注
此功能并不限于类。从中心继承的任何类(如)也将起作用。
public class ClockHub : Hub<IClock>
{
public async Task SendTimeToClients(DateTime dateTime)
{
}
}
强类型 所使用的接口是 IClock
接口。
在启动过程中,将使用 AddHostedService
启用 Worker
类 BackgroundService
。
services.AddHostedService<Worker>();
由于 SignalR 也是在 Startup
阶段启用的,在这种情况下,每个中心均附加到 ASP.NET Core 的 HTTP 请求管道中的单个终结点,每个中心由服务器上的 IHubContext<T>
表示。使用 ASP.NET Core 的 DI 功能,由宿主层实例化的其他类(如 BackgroundService
类、MVC 控制器类或 Razor 页面模型)可通过在构造期间接受 IHubContext<ClockHub, IClock>
的实例来获取对服务器端集线器的引用。
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IHubContext<ClockHub, IClock> _clockHub;
public Worker(ILogger<Worker> logger, IHubContext<ClockHub, IClock> clockHub)
{
_logger = logger;
_clockHub = clockHub;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {Time}", DateTime.Now);
await _clockHub.Clients.All.ShowTime(DateTime.Now);
await Task.Delay(1000);
}
}
}
与使用 SignalR 的 JavaScript 客户端或 .NET 桌面应用程序一样,使用 JavaScript 客户端的单页面应用程序也可以使用 .NET 客户端 SignalR ASP.NET Core,BackgroundService
或 IHostedService
实现也可用于连接到 SignalR 中心和响应事件。
ClockHubClient
类既实现了 IClock
接口,又实现了 IHostedService
接口。这样,便可以在 Startup
期间启用此功能,以便连续运行和响应来自服务器的集线器事件。
在初始化期间,ClockHubClient
将创建一个 HubConnection
的实例,并将 IClock.ShowTime
方法启用为中心的 事件的处理程序。
private readonly ILogger<ClockHubClient> _logger;
private HubConnection _connection;
public ClockHubClient(ILogger<ClockHubClient> logger)
{
_logger = logger;
_connection = new HubConnectionBuilder()
.Build();
_connection.On<DateTime>(Strings.Events.TimeSent,
dateTime => _ = ShowTime(dateTime));
}
public Task ShowTime(DateTime currentTime)
{
_logger.LogInformation("{CurrentTime}", currentTime.ToShortTimeString());
return Task.CompletedTask;
}
在 IHostedService.StartAsync
实现中,HubConnection
以异步方式启动。
public async Task StartAsync(CancellationToken cancellationToken)
{
// Loop is here to wait until the server is running
while (true)
{
try
{
await _connection.StartAsync(cancellationToken);
break;
}
catch
{
await Task.Delay(1000);
}
}
}
在 IHostedService.StopAsync
方法期间, 将异步释放。