Delen via


Host ASP.NET Core SignalR in achtergrondservices

Door Dave Pringle en Brady Gaster

Dit artikel bevat richtlijnen voor:

  • Het hosten van SignalR Hubs met een achtergrondproces dat is gehost met ASP.NET Core.
  • Berichten verzenden naar verbonden clients vanuit een .NET Core BackgroundService.

Voorbeeldcode weergeven of downloaden(hoe te downloaden)

Inschakelen SignalR bij het opstarten van de app

Het hosten van ASP.NET Core SignalR Hubs in de context van een achtergrondwerkproces is identiek aan het hosten van een hub in een ASP.NET Core-web-app. Als u aanroeptProgram.csbuilder.Services.AddSignalR, worden de vereiste services toegevoegd aan de laag ASP.NET Core Dependency Injection (DI) ter ondersteuningSignalR. De MapHub methode wordt aangeroepen om WebApplicationapp de Hub-eindpunten te verbinden in de ASP.NET Core-aanvraagpijplijn.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSignalR();
builder.Services.AddHostedService<Worker>();

var app = builder.Build();

app.MapHub<ClockHub>("/hubs/clock");

app.Run();

In het voorgaande voorbeeld implementeert de ClockHub klasse de Hub<T> klasse om een sterk getypte hub te maken. De ClockHub is geconfigureerd Program.cs om te reageren op aanvragen op het eindpunt /hubs/clock.

Voor meer informatie over sterk getypte Hubs, zie Hubs gebruiken in SignalR voor ASP.NET Core.

Opmerking

Deze functionaliteit is niet beperkt tot de Hub<T-klasse> . Elke klasse die wordt overgenomen van Hub, zoals DynamicHub, werkt.

public class ClockHub : Hub<IClock>
{
    public async Task SendMyLocalTimeToOtherClients(DateTime dateTime)
    {
        await Clients.All.ShowTime(dateTime);
    }
}

De interface die door de sterk getypte ClockHub wordt gebruikt, is de IClock interface.

public interface IClock
{
    Task ShowTime(DateTime currentTime);
}

SignalR Een hub aanroepen vanuit een achtergrondservice

Tijdens het opstarten wordt de Worker klasse, een BackgroundService, ingeschakeld met behulp van AddHostedService.

builder.Services.AddHostedService<Worker>();

Omdat SignalR ook geactiveerd is tijdens de opstartfase, waarin elke hub is gekoppeld aan een afzonderlijk eindpunt in de HTTP-aanvraagpijplijn van ASP.NET Core, wordt elke hub vertegenwoordigd door een IHubContext<T> op de server. Met behulp van de DI-functies van ASP.NET Core kunnen andere klassen die worden geïnstantieerd door de hostinglaag, zoals BackgroundService klassen, MVC-controllerklassen of Razor paginamodellen, verwijzingen krijgen naar hubs aan de serverzijde door exemplaren van IHubContext<ClockHub, IClock> tijdens de constructie te accepteren.

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);
        }
    }
}

Omdat de ExecuteAsync methode iteratief wordt aangeroepen in de achtergrondservice, worden de huidige datum en tijd van de server verzonden naar de verbonden clients met behulp van de ClockHub.

Reageren op SignalR gebeurtenissen met achtergrondservices

Net als een app met één pagina die gebruikmaakt van de JavaScript-client voor SignalRof een .NET-desktop-app met behulp van de ASP.NET Core SignalR .NET-client, kan een BackgroundService of IHostedService implementatie ook worden gebruikt om verbinding te SignalR maken met Hubs en te reageren op gebeurtenissen.

De ClockHubClient klasse implementeert zowel de IClock interface als de IHostedService interface. Op deze manier kan het tijdens het opstarten worden ingeschakeld om continu uit te voeren en te reageren op Hub-gebeurtenissen vanaf de server.

public partial class ClockHubClient : IClock, IHostedService
{
}

Tijdens de ClockHubClient initialisatie wordt een exemplaar van een HubConnection gemaakt en wordt de IClock.ShowTime methode ingeschakeld als handler voor de gebeurtenis van de 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;
}

In de IHostedService.StartAsync implementatie wordt de HubConnection app asynchroon gestart.

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);
        }
    }
}

Tijdens de IHostedService.StopAsync-methode wordt HubConnection asynchroon afgehandeld.

public async Task StopAsync(CancellationToken cancellationToken)
{
    await _connection.DisposeAsync();
}

Voorbeeldcode weergeven of downloaden(hoe te downloaden)

Inschakelen SignalR bij opstarten

Het hosten van ASP.NET Core SignalR Hubs in de context van een achtergrondwerkproces is identiek aan het hosten van een hub in een ASP.NET Core-web-app. In de Startup.ConfigureServices methode voegt het aanroepen van services.AddSignalR de vereiste services toe aan de laag van ASP.NET Core Dependency Injection (DI) om SignalR te ondersteunen. In Startup.Configurewordt de MapHub methode aangeroepen in de UseEndpoints callback om de Hub-eindpunten te verbinden in de ASP.NET Core-aanvraagpijplijn.

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");
        });
    }
}

In het voorgaande voorbeeld implementeert de ClockHub klasse de Hub<T> klasse om een sterk getypte hub te maken. De ClockHub is geconfigureerd in de Startup klasse om te reageren op aanvragen op het eindpunt /hubs/clock.

Voor meer informatie over sterk getypte Hubs, zie Hubs gebruiken in SignalR voor ASP.NET Core.

Opmerking

Deze functionaliteit is niet beperkt tot de Hub<T-klasse> . Elke klasse die wordt overgenomen van Hub, zoals DynamicHub, werkt.

public class ClockHub : Hub<IClock>
{
    public async Task SendTimeToClients(DateTime dateTime)
    {
        await Clients.All.ShowTime(dateTime);
    }
}

De interface die door de sterk getypte ClockHub wordt gebruikt, is de IClock interface.

public interface IClock
{
    Task ShowTime(DateTime currentTime);
}

SignalR Een hub aanroepen vanuit een achtergrondservice

Tijdens het opstarten wordt de Worker klasse, een BackgroundService, ingeschakeld met behulp van AddHostedService.

services.AddHostedService<Worker>();

Omdat SignalR deze functie ook is ingeschakeld tijdens de Startup fase, waarin elke hub is gekoppeld aan een afzonderlijk eindpunt in de HTTP-aanvraagpijplijn van ASP.NET Core, wordt elke hub vertegenwoordigd door een IHubContext<T> op de server. Met behulp van de DI-functies van ASP.NET Core kunnen andere klassen die worden geïnstantieerd door de hostinglaag, zoals BackgroundService klassen, MVC-controllerklassen of Razor paginamodellen, verwijzingen krijgen naar hubs aan de serverzijde door exemplaren van IHubContext<ClockHub, IClock> tijdens de constructie te accepteren.

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);
        }
    }
}

Omdat de ExecuteAsync methode iteratief wordt aangeroepen in de achtergrondservice, worden de huidige datum en tijd van de server verzonden naar de verbonden clients met behulp van de ClockHub.

Reageren op SignalR gebeurtenissen met achtergrondservices

Net als een app met één pagina die gebruikmaakt van de JavaScript-client voor SignalRof een .NET-desktop-app met behulp van de ASP.NET Core SignalR .NET-client, kan een BackgroundService of IHostedService implementatie ook worden gebruikt om verbinding te SignalR maken met Hubs en te reageren op gebeurtenissen.

De ClockHubClient klasse implementeert zowel de IClock interface als de IHostedService interface. Op deze manier kan het tijdens Startup worden ingeschakeld om continu te draaien en te reageren op Hub-gebeurtenissen vanaf de server.

public partial class ClockHubClient : IClock, IHostedService
{
}

Tijdens de ClockHubClient initialisatie wordt een exemplaar van een HubConnection gemaakt en wordt de IClock.ShowTime methode ingeschakeld als handler voor de gebeurtenis van de 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;
}

In de IHostedService.StartAsync implementatie wordt de HubConnection app asynchroon gestart.

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);
        }
    }
}

Tijdens de IHostedService.StopAsync-methode wordt HubConnection asynchroon afgehandeld.

public Task StopAsync(CancellationToken cancellationToken)
{
    return _connection.DisposeAsync();
}

Voorbeeldcode weergeven of downloaden(hoe te downloaden)

Inschakelen SignalR bij opstarten

Het hosten van ASP.NET Core SignalR Hubs in de context van een achtergrondwerkproces is identiek aan het hosten van een hub in een ASP.NET Core-web-app. In de Startup.ConfigureServices methode voegt het aanroepen van services.AddSignalR de vereiste services toe aan de laag van ASP.NET Core Dependency Injection (DI) om SignalR te ondersteunen. In Startup.Configure, de UseSignalR methode wordt aangeroepen om de Hub-eindpunten te verbinden in de ASP.NET Core-aanvraagpijplijn.

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");
        });
    }
}

In het voorgaande voorbeeld implementeert de ClockHub klasse de Hub<T> klasse om een sterk getypte hub te maken. De ClockHub is geconfigureerd in de Startup klasse om te reageren op aanvragen op het eindpunt /hubs/clock.

Voor meer informatie over sterk getypte Hubs, zie Hubs gebruiken in SignalR voor ASP.NET Core.

Opmerking

Deze functionaliteit is niet beperkt tot de Hub<T-klasse> . Elke klasse die wordt overgenomen van Hub, zoals DynamicHub, werkt.

public class ClockHub : Hub<IClock>
{
    public async Task SendTimeToClients(DateTime dateTime)
    {
        await Clients.All.ShowTime(dateTime);
    }
}

De interface die door de sterk getypte ClockHub wordt gebruikt, is de IClock interface.

public interface IClock
{
    Task ShowTime(DateTime currentTime);
}

SignalR Een hub aanroepen vanuit een achtergrondservice

Tijdens het opstarten wordt de Worker klasse, een BackgroundService, ingeschakeld met behulp van AddHostedService.

services.AddHostedService<Worker>();

Omdat SignalR deze functie ook is ingeschakeld tijdens de Startup fase, waarin elke hub is gekoppeld aan een afzonderlijk eindpunt in de HTTP-aanvraagpijplijn van ASP.NET Core, wordt elke hub vertegenwoordigd door een IHubContext<T> op de server. Met behulp van de DI-functies van ASP.NET Core kunnen andere klassen die worden geïnstantieerd door de hostinglaag, zoals BackgroundService klassen, MVC-controllerklassen of Razor paginamodellen, verwijzingen krijgen naar hubs aan de serverzijde door exemplaren van IHubContext<ClockHub, IClock> tijdens de constructie te accepteren.

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);
        }
    }
}

Omdat de ExecuteAsync methode iteratief wordt aangeroepen in de achtergrondservice, worden de huidige datum en tijd van de server verzonden naar de verbonden clients met behulp van de ClockHub.

Reageren op SignalR gebeurtenissen met achtergrondservices

Net als een app met één pagina die gebruikmaakt van de JavaScript-client voor SignalRof een .NET-desktop-app met behulp van de ASP.NET Core SignalR .NET-client, kan een BackgroundService of IHostedService implementatie ook worden gebruikt om verbinding te SignalR maken met Hubs en te reageren op gebeurtenissen.

De ClockHubClient klasse implementeert zowel de IClock interface als de IHostedService interface. Op deze manier kan het tijdens Startup worden ingeschakeld om continu te draaien en te reageren op Hub-gebeurtenissen vanaf de server.

public partial class ClockHubClient : IClock, IHostedService
{
}

Tijdens de ClockHubClient initialisatie wordt een exemplaar van een HubConnection gemaakt en wordt de IClock.ShowTime methode ingeschakeld als handler voor de gebeurtenis van de 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;
}

In de IHostedService.StartAsync implementatie wordt de HubConnection app asynchroon gestart.

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);
        }
    }
}

Tijdens de IHostedService.StopAsync-methode wordt HubConnection asynchroon afgehandeld.

public Task StopAsync(CancellationToken cancellationToken)
{
    return _connection.DisposeAsync();
}

Aanvullende bronnen