--- lang: ja-jp breaks: true --- # SignalR ハブ(Hub)についていろいろ `ASP.NET Core` 2021-09-08 > ハブの作成と使用 > https://docs.microsoft.com/ja-jp/aspnet/core/signalr/hubs#create-and-use-hubs ## ハブは一時的なものです。 * ハブクラスのプロパティに状態を保存しないでください(※クラスのプロパティに状態を格納しない)。すべてのハブメソッドの呼び出しは、新規のハブインスタンスで実行されます。 * ハブの(内部の)処理を実行中に必要となる様々な非同期メソッドを呼び出すときは `await` を使用します。たとえば、`Clients.All.SendAsync(...)` などのメソッドが `await` なしで呼び出され、`SendAsync` が終了する前にハブの(内部の)メソッドが完了すると失敗する可能性があります。 ## 必要なパッケージ ### サーバ側 ```shell= Install-Package Microsoft.AspNetCore.SignalR ``` ### クライアント側 ```shell= Install-Package Microsoft.AspNetCore.SignalR.Client ``` ## 強く型付けされたハブ クライアントからのメソッド呼び出しにインターフェイスを使用することで、スペルミス等による実行時エラーを防ぎます。 ```csharp= public interface IChatClient { Task ReceiveMessage(string user, string message); } ``` ```csharp= public class StronglyTypedChatHub : Hub<IChatClient> { public async Task SendMessage(string user, string message) { await Clients.All.ReceiveMessage(user, message); } public Task SendMessageToCaller(string user, string message) { return Clients.Caller.ReceiveMessage(user, message); } } ``` :::warning Asyncのサフィックスはメソッド名から取り除かれません。クライアントメソッドが.on('MyMethodAsync')で定義されていない限り、MyMethodAsyncを名前として使うべきではありません。 ::: ## SignalR hubs を利用するための構成 ### Startup.cs ```csharp= public void ConfigureServices(IServiceCollection services) { services.AddSignalR(); } ``` ```csharp= public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/chathub"); }); } ``` ## エラーを処理する ハブ メソッドでスローされた例外は、 メソッドを呼び出したクライアントに送信されます。 ハブが例外をスローした場合、接続は閉じられません。 既定では、は、 SignalR 一般的なエラーメッセージをクライアントに返します。 予期しない例外には、データベース接続が失敗したときにトリガーされる例外のデータベースサーバーの名前など、重要な情報が含まれていることがよくあります。 SignalR では、これらの詳細なエラーメッセージは既定でセキュリティ対策として公開されません。 クライアントに伝達する必要のある 例外的な条件 がある場合は、クラスを使用でき HubException ます。 ハブメソッドからをスローすると HubException 、 SignalR は 、メッセージ全体を未変更のままクライアントに送信します。 :::info SignalR では、 Message 例外のプロパティのみがクライアントに送信されます。 例外のスタックトレースおよびその他のプロパティは、クライアントでは使用できません。 ::: ## IHubContextインスタンスの取得 > ハブの外部からメッセージを送信する > https://docs.microsoft.com/ja-jp/aspnet/core/signalr/hubcontext > AspNetCore.Docs/aspnetcore/signalr/hubcontext/sample/ > https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/signalr/hubcontext/sample/ ## 厳密に型指定された HubContext を使用する 厳密に型指定された HubContext を挿入するには、ハブがから継承されていることを確認し Hub<T> ます。 ではなく、インターフェイスを使用して挿入 IHubContext<THub, T> IHubContext<THub> します。 ```csharp= public class ChatController : Controller { public IHubContext<ChatHub, IChatClient> _strongChatHubContext { get; } public ChatController(IHubContext<ChatHub, IChatClient> chatHubContext) { _strongChatHubContext = chatHubContext; } public async Task SendMessage(string user, string message) { await _strongChatHubContext.Clients.All.ReceiveMessage(user, message); } } ``` ## ハブ フィルターを使用する > ハブ フィルターを使用 ASP.NET CoreSignalR > https://docs.microsoft.com/ja-jp/aspnet/core/signalr/hub-filters ハブ フィルター を使用すると、ハブ メソッドがクライアントによって呼び出される前と後で処理を実行させる事が出来ます。 ## クライアントからハブ メソッドを呼び出す > SignalRASP.NET Core.NET クライアント > https://docs.microsoft.com/ja-jp/aspnet/core/signalr/dotnet-client :::warning クライアントからのハブ メソッドの呼び出しは、Azure サービスを既定モード SignalR で使用する場合にのみ サポート されます。 詳細については、「よく寄せられる質問 (azure-signalr GitHub リポジトリ)」を参照してください。 ::: ## ASP.NET Core でのログ記録と診断 SignalR https://docs.microsoft.com/ja-jp/aspnet/core/signalr/diagnostics ### サーバー側のログ記録 Program.cs ```csharp= using Microsoft.Extensions.Logging; ``` ```csharp= public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureLogging(logging => { logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug); logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); ``` ## .NET クライアントのログ記録 `Microsoft.Extensions.Logging.Console`パッケージをインストールして以下のように変更する。 `logging.AddDebug();`の場合は、`Microsoft.Extensions.Logging.Debug`パッケージをインストールする。 ```csharp= m_connection = new HubConnectionBuilder() .WithUrl("https://localhost:5001/ServiceHub_V2") //.WithUrl("http://localhost:5000/ServiceHub_V2") .ConfigureLogging(logging => { // Log to the Console logging.AddConsole(); // This will set ALL logging to Debug level logging.SetMinimumLevel(LogLevel.Debug); }) .Build(); ``` ###### tags: `SignalR` `ハブ` `Hub` `ASP.NET Core`