Hosten von ASP.NET Core SignalR in Hintergrunddiensten
Von Dave Pringle und Brady Gaster
Dieser Artikel enthält Anleitungen für Folgendes:
- Hosten von SignalR-Hubs mithilfe eines mit ASP.NET Core gehosteten Workerprozesses im Hintergrund
- Senden von Nachrichten an verbundene Clients aus einem .NET Core BackgroundService
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Aktivieren von SignalR beim Start der App
Das Hosten von ASP.NET Core SignalR-Hubs im Kontext eines Workerprozesses im Hintergrund ist identisch mit dem Hosten eines Hubs in einer ASP.NET Core-Web-App. In Program.cs
werden durch das Aufrufen von builder.Services.AddSignalR
die erforderlichen Dienste zur DI-Schicht (Dependency Injection) von ASP.NET Core hinzugefügt, um SignalR zu unterstützen. Die MapHub
-Methode wird für WebApplication
app
aufgerufen, um die Hubendpunkte mit der ASP.NET Core-Anforderungspipeline zu verbinden.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR();
builder.Services.AddHostedService<Worker>();
var app = builder.Build();
app.MapHub<ClockHub>("/hubs/clock");
app.Run();
Im vorherigen Beispiel implementiert die ClockHub
-Klasse die Hub<T>
-Klasse, um einen stark typisierten Hub zu erstellen. ClockHub
wurde in Program.cs
konfiguriert, um auf Anforderungen am Endpunkt /hubs/clock
zu reagieren.
Weitere Informationen zu stark typisierten Hubs finden Sie unter Verwenden von Hubs in SignalR für ASP.NET Core.
Hinweis
Diese Funktionalität ist nicht auf die Hub<T>-Klasse beschränkt. Jede Klasse, die von Hub erbt, z. B. DynamicHub, funktioniert.
public class ClockHub : Hub<IClock>
{
public async Task SendTimeToClients(DateTime dateTime)
{
await Clients.All.ShowTime(dateTime);
}
}
Die vom stark typisierten ClockHub
verwendete Schnittstelle ist IClock
.
public interface IClock
{
Task ShowTime(DateTime currentTime);
}
Aufrufen eines SignalR-Hubs in einem Hintergrunddienst
Während des Starts wird die Worker
-Klasse, ein BackgroundService
, mithilfe von AddHostedService
aktiviert.
builder.Services.AddHostedService<Worker>();
Da SignalR auch während der Startphase aktiviert wird, in der jeder Hub an einen individuellen Endpunkt in der HTTP-Anforderungspipeline von ASP.NET Core angefügt wird, wird jeder Hub durch IHubContext<T>
auf dem Server dargestellt. Mithilfe der DI-Features von ASP.NET Core können andere Klassen, die von der Hostingschicht instanziiert werden, wie z. B. BackgroundService
-Klassen, MVC-Controller-Klassen oder Razor-Seitenmodelle, Verweise auf serverseitige Hubs abrufen, indem sie in der Erstellungsphase Instanzen von IHubContext<ClockHub, IClock>
akzeptieren.
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, stoppingToken);
}
}
}
Da die ExecuteAsync
-Methode im Hintergrunddienst iterativ aufgerufen wird, werden das aktuelle Datum und die Uhrzeit des Servers mithilfe der ClockHub
-Methode an die verbundenen Clients gesendet.
Reagieren auf SignalR-Ereignisse mithilfe von Hintergrunddiensten
Wie eine Single-Page-App, die den JavaScript-Client für SignalR verwendet, oder eine .NET-Desktop-App, die den ASP.NET Core SignalR .NET-Client nutzt, kann auch eine BackgroundService
- oder IHostedService
-Implementierung verwendet werden, um sich mit SignalR-Hubs zu verbinden und auf Ereignisse zu reagieren.
Die ClockHubClient
-Klasse implementiert die Schnittstellen IClock
und IHostedService
. Auf diese Weise kann sie beim Start aktiviert werden, um kontinuierlich ausgeführt zu werden und auf Hubereignisse des Servers zu reagieren.
public partial class ClockHubClient : IClock, IHostedService
{
}
Während der Initialisierung erstellt ClockHubClient
eine Instanz von HubConnection
und aktiviert die IClock.ShowTime
-Methode als Handler für das ShowTime
-Ereignis des Hubs.
private readonly ILogger<ClockHubClient> _logger;
private HubConnection _connection;
public ClockHubClient(ILogger<ClockHubClient> logger)
{
_logger = logger;
_connection = new HubConnectionBuilder()
.WithUrl(Strings.HubUrl)
.Build();
_connection.On<DateTime>(Strings.Events.TimeSent, ShowTime);
}
public Task ShowTime(DateTime currentTime)
{
_logger.LogInformation("{CurrentTime}", currentTime.ToShortTimeString());
return Task.CompletedTask;
}
In der IHostedService.StartAsync
-Implementierung wird HubConnection
asynchron gestartet.
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, cancellationToken);
}
}
}
Während der IHostedService.StopAsync
-Methode wird HubConnection
asynchron verworfen.
public async Task StopAsync(CancellationToken cancellationToken)
{
await _connection.DisposeAsync();
}
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Aktivieren von SignalR beim Start
Das Hosten von ASP.NET Core SignalR-Hubs im Kontext eines Workerprozesses im Hintergrund ist identisch mit dem Hosten eines Hubs in einer ASP.NET Core-Web-App. In der Startup.ConfigureServices
-Methode werden durch das Aufrufen von services.AddSignalR
die erforderlichen Dienste zur DI-Schicht (Dependency Injection) von ASP.NET Core hinzugefügt, um SignalR zu unterstützen. In Startup.Configure
wird die MapHub
-Methode im UseEndpoints
-Rückruf aufgerufen, um die Hubendpunkte mit der ASP.NET Core-Anforderungspipeline zu verbinden.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddHostedService<Worker>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ClockHub>("/hubs/clock");
});
}
}
Im vorherigen Beispiel implementiert die ClockHub
-Klasse die Hub<T>
-Klasse, um einen stark typisierten Hub zu erstellen. Der ClockHub
wurde in der Startup
-Klasse konfiguriert, um auf Anforderungen am Endpunkt /hubs/clock
zu reagieren.
Weitere Informationen zu stark typisierten Hubs finden Sie unter Verwenden von Hubs in SignalR für ASP.NET Core.
Hinweis
Diese Funktionalität ist nicht auf die Hub<T>-Klasse beschränkt. Jede Klasse, die von Hub erbt, z. B. DynamicHub, funktioniert.
public class ClockHub : Hub<IClock>
{
public async Task SendTimeToClients(DateTime dateTime)
{
await Clients.All.ShowTime(dateTime);
}
}
Die vom stark typisierten ClockHub
verwendete Schnittstelle ist IClock
.
public interface IClock
{
Task ShowTime(DateTime currentTime);
}
Aufrufen eines SignalR-Hubs in einem Hintergrunddienst
Während des Starts wird die Worker
-Klasse, ein BackgroundService
, mithilfe von AddHostedService
aktiviert.
services.AddHostedService<Worker>();
Da SignalR auch während der Startup
-Phase aktiviert wird, in der jeder Hub an einen individuellen Endpunkt in der HTTP-Anforderungspipeline von ASP.NET Core angefügt wird, wird jeder Hub durch IHubContext<T>
auf dem Server dargestellt. Mithilfe der DI-Features von ASP.NET Core können andere Klassen, die von der Hostingschicht instanziiert werden, wie z. B. BackgroundService
-Klassen, MVC-Controller-Klassen oder Razor-Seitenmodelle, Verweise auf serverseitige Hubs abrufen, indem sie in der Erstellungsphase Instanzen von IHubContext<ClockHub, IClock>
akzeptieren.
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);
}
}
}
Da die ExecuteAsync
-Methode im Hintergrunddienst iterativ aufgerufen wird, werden das aktuelle Datum und die Uhrzeit des Servers mithilfe der ClockHub
-Methode an die verbundenen Clients gesendet.
Reagieren auf SignalR-Ereignisse mithilfe von Hintergrunddiensten
Wie eine Single-Page-App, die den JavaScript-Client für SignalR verwendet, oder eine .NET-Desktop-App, die den ASP.NET Core SignalR .NET-Client nutzt, kann auch eine BackgroundService
- oder IHostedService
-Implementierung verwendet werden, um sich mit SignalR-Hubs zu verbinden und auf Ereignisse zu reagieren.
Die ClockHubClient
-Klasse implementiert die Schnittstellen IClock
und IHostedService
. Auf diese Weise kann sie beim Startup
aktiviert werden, um kontinuierlich ausgeführt zu werden und auf Hubereignisse auf dem Server zu reagieren.
public partial class ClockHubClient : IClock, IHostedService
{
}
Während der Initialisierung erstellt ClockHubClient
eine Instanz von HubConnection
und aktiviert die IClock.ShowTime
-Methode als Handler für das ShowTime
-Ereignis des Hubs.
private readonly ILogger<ClockHubClient> _logger;
private HubConnection _connection;
public ClockHubClient(ILogger<ClockHubClient> logger)
{
_logger = logger;
_connection = new HubConnectionBuilder()
.WithUrl(Strings.HubUrl)
.Build();
_connection.On<DateTime>(Strings.Events.TimeSent, ShowTime);
}
public Task ShowTime(DateTime currentTime)
{
_logger.LogInformation("{CurrentTime}", currentTime.ToShortTimeString());
return Task.CompletedTask;
}
In der IHostedService.StartAsync
-Implementierung wird HubConnection
asynchron gestartet.
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);
}
}
}
Während der IHostedService.StopAsync
-Methode wird HubConnection
asynchron verworfen.
public Task StopAsync(CancellationToken cancellationToken)
{
return _connection.DisposeAsync();
}
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Aktivieren von SignalR beim Start
Das Hosten von ASP.NET Core SignalR-Hubs im Kontext eines Workerprozesses im Hintergrund ist identisch mit dem Hosten eines Hubs in einer ASP.NET Core-Web-App. In der Startup.ConfigureServices
-Methode werden durch das Aufrufen von services.AddSignalR
die erforderlichen Dienste zur DI-Schicht (Dependency Injection) von ASP.NET Core hinzugefügt, um SignalR zu unterstützen. In Startup.Configure
wird die UseSignalR
-Methode aufgerufen, um die Hubendpunkte mit der ASP.NET Core-Anforderungspipeline zu verbinden.
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");
});
}
}
Im vorherigen Beispiel implementiert die ClockHub
-Klasse die Hub<T>
-Klasse, um einen stark typisierten Hub zu erstellen. Der ClockHub
wurde in der Startup
-Klasse konfiguriert, um auf Anforderungen am Endpunkt /hubs/clock
zu reagieren.
Weitere Informationen zu stark typisierten Hubs finden Sie unter Verwenden von Hubs in SignalR für ASP.NET Core.
Hinweis
Diese Funktionalität ist nicht auf die Hub<T>-Klasse beschränkt. Jede Klasse, die von Hub erbt, z. B. DynamicHub, funktioniert.
public class ClockHub : Hub<IClock>
{
public async Task SendTimeToClients(DateTime dateTime)
{
await Clients.All.ShowTime(dateTime);
}
}
Die vom stark typisierten ClockHub
verwendete Schnittstelle ist IClock
.
public interface IClock
{
Task ShowTime(DateTime currentTime);
}
Aufrufen eines SignalR-Hubs in einem Hintergrunddienst
Während des Starts wird die Worker
-Klasse, ein BackgroundService
, mithilfe von AddHostedService
aktiviert.
services.AddHostedService<Worker>();
Da SignalR auch während der Startup
-Phase aktiviert wird, in der jeder Hub an einen individuellen Endpunkt in der HTTP-Anforderungspipeline von ASP.NET Core angefügt wird, wird jeder Hub durch IHubContext<T>
auf dem Server dargestellt. Mithilfe der DI-Features von ASP.NET Core können andere Klassen, die von der Hostingschicht instanziiert werden, wie z. B. BackgroundService
-Klassen, MVC-Controller-Klassen oder Razor-Seitenmodelle, Verweise auf serverseitige Hubs abrufen, indem sie in der Erstellungsphase Instanzen von IHubContext<ClockHub, IClock>
akzeptieren.
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);
}
}
}
Da die ExecuteAsync
-Methode im Hintergrunddienst iterativ aufgerufen wird, werden das aktuelle Datum und die Uhrzeit des Servers mithilfe der ClockHub
-Methode an die verbundenen Clients gesendet.
Reagieren auf SignalR-Ereignisse mithilfe von Hintergrunddiensten
Wie eine Single-Page-App, die den JavaScript-Client für SignalR verwendet, oder eine .NET-Desktop-App, die den ASP.NET Core SignalR .NET-Client nutzt, kann auch eine BackgroundService
- oder IHostedService
-Implementierung verwendet werden, um sich mit SignalR-Hubs zu verbinden und auf Ereignisse zu reagieren.
Die ClockHubClient
-Klasse implementiert die Schnittstellen IClock
und IHostedService
. Auf diese Weise kann sie beim Startup
aktiviert werden, um kontinuierlich ausgeführt zu werden und auf Hubereignisse auf dem Server zu reagieren.
public partial class ClockHubClient : IClock, IHostedService
{
}
Während der Initialisierung erstellt ClockHubClient
eine Instanz von HubConnection
und aktiviert die IClock.ShowTime
-Methode als Handler für das ShowTime
-Ereignis des Hubs.
private readonly ILogger<ClockHubClient> _logger;
private HubConnection _connection;
public ClockHubClient(ILogger<ClockHubClient> logger)
{
_logger = logger;
_connection = new HubConnectionBuilder()
.WithUrl(Strings.HubUrl)
.Build();
_connection.On<DateTime>(Strings.Events.TimeSent,
dateTime => _ = ShowTime(dateTime));
}
public Task ShowTime(DateTime currentTime)
{
_logger.LogInformation("{CurrentTime}", currentTime.ToShortTimeString());
return Task.CompletedTask;
}
In der IHostedService.StartAsync
-Implementierung wird HubConnection
asynchron gestartet.
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);
}
}
}
Während der IHostedService.StopAsync
-Methode wird HubConnection
asynchron verworfen.
public Task StopAsync(CancellationToken cancellationToken)
{
return _connection.DisposeAsync();
}