Узел ASP.NET Core SignalR в фоновых службах

Дэйв Pringle и Брэди Гастер

В этой статье приведены рекомендации по следующим вопросам:

  • Центры размещения SignalR с использованием фонового рабочего процесса, размещенного с ASP.NET Core.
  • Отправка сообщений подключенным клиентам из .NET Core BackgroundService.

Просмотрите или скачайте пример кода (описание процедуры скачивания)

Включение SignalR при запуске приложения

Размещение ASP.NET Core SignalR Hubs в контексте фонового рабочего процесса идентично размещению Концентратора в веб-приложении ASP.NET Core. При Program.csвызове builder.Services.AddSignalR добавляются необходимые службы в уровень внедрения основных зависимостей (DI) ASP.NET для поддержки SignalR. Метод MapHub вызывается для WebApplicationapp подключения конечных точек Концентратора в конвейере запросов ASP.NET Core.

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

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

app.Run();

В предыдущем примере ClockHub класс реализует Hub<T> класс для создания строго типизированного концентратора. Он ClockHub настроен для Program.cs реагирования на запросы в конечной точке /hubs/clock.

Дополнительные сведения о строго типизированных центрах см. в разделе "Использование центров" SignalR для ASP.NET Core.

Примечание.

Эта функция не ограничивается классом Hub<T> . Любой класс, наследующий от Концентратора, например DynamicHub, работает.

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

Интерфейс, используемый строго типизированным ClockHub интерфейсом IClock .

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

Вызов концентратора SignalR из фоновой службы

Во время запуска Worker класс, a BackgroundService, включен с помощью AddHostedService.

builder.Services.AddHostedService<Worker>();

Так как SignalR он также включен во время этапа запуска, в котором каждый концентратор подключен к отдельной конечной точке в конвейере HTTP-запроса Core ASP.NET, каждый концентратор представлен IHubContext<T> на сервере. Используя функции di ASP.NET Core, другие классы, созданные уровнем размещения, например 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, stoppingToken);
        }
    }
}

ExecuteAsync Так как метод называется итеративно в фоновой службе, текущая дата и время сервера отправляются подключенным клиентам с помощью .ClockHub

Реагирование на SignalR события с помощью фоновых служб

Например, одностраничное приложение с помощью клиента JavaScript или SignalRклассического приложения .NET с помощью клиента .NET Core ASP.NET Core SignalR , можно BackgroundServiceIHostedService также использовать для подключения к SignalR центрам и реагирования на события.

Класс ClockHubClient реализует интерфейс IClock и IHostedService интерфейс. Таким образом, его можно включить во время запуска непрерывно и реагировать на события Концентратора с сервера.

public partial class ClockHubClient : IClock, IHostedService
{
}

Во время инициализации создается ClockHubClient экземпляр объекта HubConnection и включается IClock.ShowTime метод в качестве обработчика события Концентратора 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;
}

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

IHostedService.StopAsync Во время метода HubConnection удаляется асинхронно.

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

Просмотрите или скачайте пример кода (описание процедуры скачивания)

Включение SignalR при запуске

Размещение ASP.NET Core SignalR Hubs в контексте фонового рабочего процесса идентично размещению Концентратора в веб-приложении ASP.NET Core. В методе Startup.ConfigureServices вызов services.AddSignalR добавляет необходимые службы в уровень внедрения основных зависимостей ASP.NET (DI) для поддержки SignalR. MapHub В Startup.Configureэтом случае метод вызывается в обратном UseEndpoints вызове для подключения конечных точек Концентратора в конвейере запросов 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");
        });
    }
}

В предыдущем примере ClockHub класс реализует Hub<T> класс для создания строго типизированного концентратора. Он ClockHub был настроен в Startup классе для реагирования на запросы в конечной точке /hubs/clock.

Дополнительные сведения о строго типизированных центрах см. в разделе "Использование центров" SignalR для ASP.NET Core.

Примечание.

Эта функция не ограничивается классом Hub<T> . Любой класс, наследующий от Концентратора, например DynamicHub, работает.

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

Интерфейс, используемый строго типизированным ClockHub интерфейсом IClock .

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

Вызов концентратора SignalR из фоновой службы

Во время запуска Worker класс, a BackgroundService, включен с помощью AddHostedService.

services.AddHostedService<Worker>();

Так как SignalR он также включен на Startup этапе, в котором каждый концентратор подключен к отдельной конечной точке в конвейере HTTP-запроса Core ASP.NET, каждый концентратор представлен IHubContext<T> на сервере. Используя функции di ASP.NET Core, другие классы, созданные уровнем размещения, например 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);
        }
    }
}

ExecuteAsync Так как метод называется итеративно в фоновой службе, текущая дата и время сервера отправляются подключенным клиентам с помощью .ClockHub

Реагирование на SignalR события с помощью фоновых служб

Например, одностраничное приложение с помощью клиента JavaScript или SignalRклассического приложения .NET с помощью клиента .NET Core ASP.NET Core SignalR , можно BackgroundServiceIHostedService также использовать для подключения к SignalR центрам и реагирования на события.

Класс ClockHubClient реализует интерфейс IClock и IHostedService интерфейс. Таким образом, его можно включить во время Startup непрерывного выполнения и реагирования на события Концентратора с сервера.

public partial class ClockHubClient : IClock, IHostedService
{
}

Во время инициализации создается ClockHubClient экземпляр объекта HubConnection и включается IClock.ShowTime метод в качестве обработчика события Концентратора 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;
}

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 Во время метода HubConnection удаляется асинхронно.

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

Просмотрите или скачайте пример кода (описание процедуры скачивания)

Включение SignalR при запуске

Размещение ASP.NET Core SignalR Hubs в контексте фонового рабочего процесса идентично размещению Концентратора в веб-приложении ASP.NET Core. В методе Startup.ConfigureServices вызов services.AddSignalR добавляет необходимые службы в уровень внедрения основных зависимостей ASP.NET (DI) для поддержки SignalR. UseSignalR В Startup.Configureэтом случае метод вызывается для подключения конечных точек Концентратора в конвейере запросов 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> класс для создания строго типизированного концентратора. Он ClockHub был настроен в Startup классе для реагирования на запросы в конечной точке /hubs/clock.

Дополнительные сведения о строго типизированных центрах см. в разделе "Использование центров" SignalR для ASP.NET Core.

Примечание.

Эта функция не ограничивается классом Hub<T> . Любой класс, наследующий от Концентратора, например DynamicHub, работает.

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

Интерфейс, используемый строго типизированным ClockHub интерфейсом IClock .

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

Вызов концентратора SignalR из фоновой службы

Во время запуска Worker класс, a BackgroundService, включен с помощью AddHostedService.

services.AddHostedService<Worker>();

Так как SignalR он также включен на Startup этапе, в котором каждый концентратор подключен к отдельной конечной точке в конвейере HTTP-запроса Core ASP.NET, каждый концентратор представлен IHubContext<T> на сервере. Используя функции di ASP.NET Core, другие классы, созданные уровнем размещения, например 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);
        }
    }
}

ExecuteAsync Так как метод называется итеративно в фоновой службе, текущая дата и время сервера отправляются подключенным клиентам с помощью .ClockHub

Реагирование на SignalR события с помощью фоновых служб

Например, одностраничное приложение с помощью клиента JavaScript или SignalRклассического приложения .NET с помощью клиента .NET Core ASP.NET Core SignalR , можно BackgroundServiceIHostedService также использовать для подключения к SignalR центрам и реагирования на события.

Класс ClockHubClient реализует интерфейс IClock и IHostedService интерфейс. Таким образом, его можно включить во время Startup непрерывного выполнения и реагирования на события Концентратора с сервера.

public partial class ClockHubClient : IClock, IHostedService
{
}

Во время инициализации создается ClockHubClient экземпляр объекта HubConnection и включается IClock.ShowTime метод в качестве обработчика события Концентратора 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;
}

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 Во время метода HubConnection удаляется асинхронно.

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

Дополнительные ресурсы