バックグラウンド サービスでの ASP.NET Core SignalR のホスティング
作成者: Dave Pringle、Brady Gaster
この記事では、以下に関するガイダンスを提供します。
- ASP.NET Core にホストされているバックグラウンド ワーカー プロセスを使用した SignalR ハブのホスティング。
- .NET Core BackgroundService 内から接続されたクライアントへのメッセージの送信。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
アプリの起動時に SignalR を有効にする
バックグラウンド ワーカー プロセスのコンテキストでの ASP.NET Core SignalR ハブのホスティングは、ASP.NET Core Web アプリ内でのハブのホスティングと同じです。 Program.cs
で builder.Services.AddSignalR
を呼び出すと、SignalR をサポートするために必要なサービスが ASP.NET Core 依存関係の挿入 (DI) レイヤーに追加されます。 WebApplication
app
上で MapHub
メソッドが呼び出され、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
は、エンドポイント /hubs/clock
で要求に応答するように Program.cs
内で構成されています。
厳密に型指定されたハブの詳細については、ASP.NET Core の SignalR でのハブの使用に関するページをご覧ください。
Note
この機能は 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
クラスである BackgroundService
は、AddHostedService
を使用して有効化されます。
builder.Services.AddHostedService<Worker>();
また、SignalR は、各ハブが 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, stoppingToken);
}
}
}
ExecuteAsync
メソッドがバックグラウンド サービス内で繰り返し呼び出されると、サーバーの現在の日付と時刻は ClockHub
を使用して接続されたクライアントに送信されます。
バック グラウンド サービスを使用して SignalR イベントに対応する
SignalR 用の JavaScript クライアントを使用するシングル ページ アプリや、ASP.NET Core SignalR .NET Client を使用する .NET デスクトップ アプリのように、BackgroundService
または IHostedService
の実装を使用して 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 ハブのホスティングは、ASP.NET Core Web アプリ内でのハブのホスティングと同じです。 Startup.ConfigureServices
メソッドで services.AddSignalR
を呼び出すと、SignalR をサポートするために必要なサービスが ASP.NET Core 依存関係の挿入 (DI) レイヤーに追加されます。 Startup.Configure
では、MapHub
メソッドが 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
は、エンドポイント /hubs/clock
での要求に応答するように Startup
クラス内で構成されています。
厳密に型指定されたハブの詳細については、ASP.NET Core の SignalR でのハブの使用に関するページをご覧ください。
Note
この機能は 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
クラスである BackgroundService
は、AddHostedService
を使用して有効化されます。
services.AddHostedService<Worker>();
また、SignalR は、各ハブが ASP.NET Core の HTTP 要求パイプライン内の個々のエンドポイントに接続される Startup
フェーズ中にも有効になっているので、各ハブはサーバー上の 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);
}
}
}
ExecuteAsync
メソッドがバックグラウンド サービス内で繰り返し呼び出されると、サーバーの現在の日付と時刻は ClockHub
を使用して接続されたクライアントに送信されます。
バック グラウンド サービスを使用して SignalR イベントに対応する
SignalR 用の JavaScript クライアントを使用するシングル ページ アプリや、ASP.NET Core SignalR .NET Client を使用する .NET デスクトップ アプリのように、BackgroundService
または IHostedService
の実装を使用して 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 ハブのホスティングは、ASP.NET Core Web アプリ内でのハブのホスティングと同じです。 Startup.ConfigureServices
メソッドで services.AddSignalR
を呼び出すと、SignalR をサポートするために必要なサービスが ASP.NET Core 依存関係の挿入 (DI) レイヤーに追加されます。 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>
クラスが実装されています。 ClockHub
は、エンドポイント /hubs/clock
での要求に応答するように Startup
クラス内で構成されています。
厳密に型指定されたハブの詳細については、ASP.NET Core の SignalR でのハブの使用に関するページをご覧ください。
Note
この機能は 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
クラスである BackgroundService
は、AddHostedService
を使用して有効化されます。
services.AddHostedService<Worker>();
また、SignalR は、各ハブが ASP.NET Core の HTTP 要求パイプライン内の個々のエンドポイントに接続される Startup
フェーズ中にも有効になっているので、各ハブはサーバー上の 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);
}
}
}
ExecuteAsync
メソッドがバックグラウンド サービス内で繰り返し呼び出されると、サーバーの現在の日付と時刻は ClockHub
を使用して接続されたクライアントに送信されます。
バック グラウンド サービスを使用して SignalR イベントに対応する
SignalR 用の JavaScript クライアントを使用するシングル ページ アプリや、ASP.NET Core SignalR .NET Client を使用する .NET デスクトップ アプリのように、BackgroundService
または IHostedService
の実装を使用して 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();
}
その他のリソース
ASP.NET Core