Ospitare ASP.NET Core SignalR nei servizi in background
Di Dave Pringle e Brady Gaster
Questo articolo fornisce indicazioni per:
- Hosting SignalR di Hub usando un processo di lavoro in background ospitato con ASP.NET Core.
- Invio di messaggi ai client connessi da un servizio background .NET Core.
Visualizzare o scaricare il codice di esempio (procedura per il download)
Abilitare SignalR all'avvio dell'app
L'hosting di ASP.NET Core SignalR Hub nel contesto di un processo di lavoro in background è identico all'hosting di un hub in un'app Web ASP.NET Core. In Program.cs
la chiamata builder.Services.AddSignalR
aggiunge i servizi necessari al livello ASP.NET core dependency injection (DI) per supportare SignalR. Il MapHub
metodo viene chiamato su WebApplication
app
per connettere gli endpoint hub nella pipeline di richiesta core ASP.NET.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR();
builder.Services.AddHostedService<Worker>();
var app = builder.Build();
app.MapHub<ClockHub>("/hubs/clock");
app.Run();
Nell'esempio precedente la ClockHub
classe implementa la Hub<T>
classe per creare un hub fortemente tipizzato. L'oggetto ClockHub
è stato configurato in Program.cs
per rispondere alle richieste nell'endpoint /hubs/clock
.
Per altre informazioni sugli hub fortemente tipizzato, vedere Usare hub in SignalR per ASP.NET Core.
Nota
Questa funzionalità non è limitata alla classe T dell'hub<.> Qualsiasi classe che eredita da Hub, ad esempio DynamicHub, funziona.
public class ClockHub : Hub<IClock>
{
public async Task SendTimeToClients(DateTime dateTime)
{
await Clients.All.ShowTime(dateTime);
}
}
L'interfaccia usata dall'oggetto fortemente tipizzato ClockHub
è l'interfaccia IClock
.
public interface IClock
{
Task ShowTime(DateTime currentTime);
}
Chiamare un SignalR hub da un servizio in background
Durante l'avvio, la Worker
classe , è BackgroundService
abilitata tramite AddHostedService
.
builder.Services.AddHostedService<Worker>();
Poiché SignalR è abilitato anche durante la fase di avvio, in cui ogni hub è collegato a un singolo endpoint nella pipeline di richiesta HTTP di ASP.NET Core, ogni hub è rappresentato da un IHubContext<T>
nel server. Usando le funzionalità di inserimento delle dipendenze di ASP.NET Core, altre classi create dal livello di hosting, ad esempio BackgroundService
classi, classi di controller MVC o Razor modelli di pagina, possono ottenere riferimenti agli hub lato server accettando istanze di IHubContext<ClockHub, IClock>
durante la costruzione.
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);
}
}
}
Poiché il ExecuteAsync
metodo viene chiamato iterativamente nel servizio in background, la data e l'ora correnti del server vengono inviate ai client connessi usando .ClockHub
Reagire agli SignalR eventi con i servizi in background
Analogamente a un'app a pagina singola che usa il client JavaScript per SignalRo un'app desktop .NET tramite il client .NET di ASP.NET Core SignalR , è possibile usare un'implementazione BackgroundService
o IHostedService
per connettersi a SignalR Hub e rispondere agli eventi.
La ClockHubClient
classe implementa sia l'interfaccia IClock
che l'interfaccia IHostedService
. In questo modo è possibile abilitarlo durante l'avvio per l'esecuzione continua e rispondere agli eventi hub dal server.
public partial class ClockHubClient : IClock, IHostedService
{
}
Durante l'inizializzazione, crea un'istanza ClockHubClient
di e HubConnection
abilita il IClock.ShowTime
metodo come gestore per l'evento dell'hub ShowTime
.
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;
}
Nell'implementazione l'oggetto IHostedService.StartAsync
HubConnection
viene avviato in modo asincrono.
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);
}
}
}
Durante il IHostedService.StopAsync
metodo , l'oggetto HubConnection
viene eliminato in modo asincrono.
public async Task StopAsync(CancellationToken cancellationToken)
{
await _connection.DisposeAsync();
}
Visualizzare o scaricare il codice di esempio (procedura per il download)
Abilita SignalR all'avvio
L'hosting di ASP.NET Core SignalR Hub nel contesto di un processo di lavoro in background è identico all'hosting di un hub in un'app Web ASP.NET Core. Startup.ConfigureServices
Nel metodo, la chiamata services.AddSignalR
aggiunge i servizi necessari al livello di inserimento delle dipendenze di base (DI) ASP.NET per supportare SignalR. In Startup.Configure
il MapHub
metodo viene chiamato nel UseEndpoints
callback per connettere gli endpoint hub nella pipeline di richiesta ASP.NET Core.
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");
});
}
}
Nell'esempio precedente la ClockHub
classe implementa la Hub<T>
classe per creare un hub fortemente tipizzato. L'oggetto ClockHub
è stato configurato nella Startup
classe per rispondere alle richieste nell'endpoint /hubs/clock
.
Per altre informazioni sugli hub fortemente tipizzato, vedere Usare hub in SignalR per ASP.NET Core.
Nota
Questa funzionalità non è limitata alla classe T dell'hub<.> Qualsiasi classe che eredita da Hub, ad esempio DynamicHub, funziona.
public class ClockHub : Hub<IClock>
{
public async Task SendTimeToClients(DateTime dateTime)
{
await Clients.All.ShowTime(dateTime);
}
}
L'interfaccia usata dall'oggetto fortemente tipizzato ClockHub
è l'interfaccia IClock
.
public interface IClock
{
Task ShowTime(DateTime currentTime);
}
Chiamare un SignalR hub da un servizio in background
Durante l'avvio, la Worker
classe , è BackgroundService
abilitata tramite AddHostedService
.
services.AddHostedService<Worker>();
Poiché SignalR è abilitato anche durante la Startup
fase, in cui ogni hub è collegato a un singolo endpoint nella pipeline di richiesta HTTP di ASP.NET Core, ogni hub è rappresentato da un IHubContext<T>
nel server. Usando le funzionalità di inserimento delle dipendenze di ASP.NET Core, altre classi create dal livello di hosting, ad esempio BackgroundService
classi, classi di controller MVC o Razor modelli di pagina, possono ottenere riferimenti agli hub lato server accettando istanze di IHubContext<ClockHub, IClock>
durante la costruzione.
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);
}
}
}
Poiché il ExecuteAsync
metodo viene chiamato iterativamente nel servizio in background, la data e l'ora correnti del server vengono inviate ai client connessi usando .ClockHub
Reagire agli SignalR eventi con i servizi in background
Analogamente a un'app a pagina singola che usa il client JavaScript per SignalRo un'app desktop .NET tramite il client .NET di ASP.NET Core SignalR , è possibile usare un'implementazione BackgroundService
o IHostedService
per connettersi a SignalR Hub e rispondere agli eventi.
La ClockHubClient
classe implementa sia l'interfaccia IClock
che l'interfaccia IHostedService
. In questo modo è possibile abilitarlo durante Startup
l'esecuzione continua e rispondere agli eventi hub dal server.
public partial class ClockHubClient : IClock, IHostedService
{
}
Durante l'inizializzazione, crea un'istanza ClockHubClient
di e HubConnection
abilita il IClock.ShowTime
metodo come gestore per l'evento dell'hub ShowTime
.
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;
}
Nell'implementazione l'oggetto IHostedService.StartAsync
HubConnection
viene avviato in modo asincrono.
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);
}
}
}
Durante il IHostedService.StopAsync
metodo , l'oggetto HubConnection
viene eliminato in modo asincrono.
public Task StopAsync(CancellationToken cancellationToken)
{
return _connection.DisposeAsync();
}
Visualizzare o scaricare il codice di esempio (procedura per il download)
Abilita SignalR all'avvio
L'hosting di ASP.NET Core SignalR Hub nel contesto di un processo di lavoro in background è identico all'hosting di un hub in un'app Web ASP.NET Core. Startup.ConfigureServices
Nel metodo, la chiamata services.AddSignalR
aggiunge i servizi necessari al livello di inserimento delle dipendenze di base (DI) ASP.NET per supportare SignalR. In Startup.Configure
il UseSignalR
metodo viene chiamato per connettere gli endpoint hub nella pipeline di richiesta core ASP.NET.
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");
});
}
}
Nell'esempio precedente la ClockHub
classe implementa la Hub<T>
classe per creare un hub fortemente tipizzato. L'oggetto ClockHub
è stato configurato nella Startup
classe per rispondere alle richieste nell'endpoint /hubs/clock
.
Per altre informazioni sugli hub fortemente tipizzato, vedere Usare hub in SignalR per ASP.NET Core.
Nota
Questa funzionalità non è limitata alla classe T dell'hub<.> Qualsiasi classe che eredita da Hub, ad esempio DynamicHub, funziona.
public class ClockHub : Hub<IClock>
{
public async Task SendTimeToClients(DateTime dateTime)
{
await Clients.All.ShowTime(dateTime);
}
}
L'interfaccia usata dall'oggetto fortemente tipizzato ClockHub
è l'interfaccia IClock
.
public interface IClock
{
Task ShowTime(DateTime currentTime);
}
Chiamare un SignalR hub da un servizio in background
Durante l'avvio, la Worker
classe , è BackgroundService
abilitata tramite AddHostedService
.
services.AddHostedService<Worker>();
Poiché SignalR è abilitato anche durante la Startup
fase, in cui ogni hub è collegato a un singolo endpoint nella pipeline di richiesta HTTP di ASP.NET Core, ogni hub è rappresentato da un IHubContext<T>
nel server. Usando le funzionalità di inserimento delle dipendenze di ASP.NET Core, altre classi create dal livello di hosting, ad esempio BackgroundService
classi, classi di controller MVC o Razor modelli di pagina, possono ottenere riferimenti agli hub lato server accettando istanze di IHubContext<ClockHub, IClock>
durante la costruzione.
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);
}
}
}
Poiché il ExecuteAsync
metodo viene chiamato iterativamente nel servizio in background, la data e l'ora correnti del server vengono inviate ai client connessi usando .ClockHub
Reagire agli SignalR eventi con i servizi in background
Analogamente a un'app a pagina singola che usa il client JavaScript per SignalRo un'app desktop .NET tramite il client .NET di ASP.NET Core SignalR , è possibile usare un'implementazione BackgroundService
o IHostedService
per connettersi a SignalR Hub e rispondere agli eventi.
La ClockHubClient
classe implementa sia l'interfaccia IClock
che l'interfaccia IHostedService
. In questo modo è possibile abilitarlo durante Startup
l'esecuzione continua e rispondere agli eventi hub dal server.
public partial class ClockHubClient : IClock, IHostedService
{
}
Durante l'inizializzazione, crea un'istanza ClockHubClient
di e HubConnection
abilita il IClock.ShowTime
metodo come gestore per l'evento dell'hub ShowTime
.
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;
}
Nell'implementazione l'oggetto IHostedService.StartAsync
HubConnection
viene avviato in modo asincrono.
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);
}
}
}
Durante il IHostedService.StopAsync
metodo , l'oggetto HubConnection
viene eliminato in modo asincrono.
public Task StopAsync(CancellationToken cancellationToken)
{
return _connection.DisposeAsync();
}