-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ASPNETSignalR
- 戻る(OWIN(
MS_OWIN.md)、WebSocket)- ASP.NET SignalR
- ASP.NET にリアルタイム・ウェブ機能を追加するためのライブラリ
-
WebSocket に依存しないので、
WebSocket の新規採用の可能性が低くなった以降も可能性はある技術と言える。
補足(最新化): 本ページは ASP.NET SignalR(.NET Framework、
Microsoft.AspNet.SignalR.*)についての内容である。 新規開発では ASP.NET Core SignalR (Microsoft.AspNetCore.SignalR)を使う。主な差異は次のとおり。
ASP.NET SignalR ASP.NET Core SignalR トランスポート WebSocket / SSE / Long-polling / Forever Frame WebSocket / SSE / Long-polling プロトコル JSON のみ JSON、MessagePack 自動再接続 あり 既定では無い( withAutomaticReconnect()が必要)JS クライアント jQuery 依存 依存なし( @microsoft/signalr)プロキシ自動生成 あり( /signalr/hubs)無し( invokeで名前指定)スケールアウト Redis / Service Bus / SQL Server Redis / Azure SignalR Service 相互運用性は無いため、サーバとクライアントの両方を同時に移行する必要がある。
下位トランスポートには、
- WebSocket
- WebSocket 以外
がある。
SignalR には、PersistentConnection と Hub という 2 つの API が存在する。
- サーバとクライアントの間での「持続的な接続」を提供する。
- 下位トランスポートの上位に実装されている。
- 1 つのメッセージを送受信する機能しかない。
- クライアントを管理するための機能も用意されている。
-
SignalR を使ったアプリの開発では主に Hub を使う。
-
PersistentConnection の上位に実装されている(RPC 的な高レベル API)。
- クライアント/サーバ間のメソッド呼び出しという基本的な機能を提供している。
- ASP.NET MVC のアクション・フィルタに相当する「HubPipeline」と呼ばれる
機能が実装されている。- これを利用してクライアントの認証が実装されている。
- 認証目的以外にも開発者が自由に拡張できる。
- オーバーヘッドが大きい。
- リクエストの解析
- リフレクションを使ったメソッド呼び出し
補足: ASP.NET Core SignalR では
PersistentConnectionは廃止され、Hub のみになった。
-
Contextプロパティ-
HttpContextなどの振る舞いは、下位トランスポートによって異なるので使用しない。 - 例えば、WebSocket が下位トランスポートの場合、
HttpContextは接続時の情報に固定される。
-
-
Hub.Contextプロパティ-
HubCallerContextクラスのインスタンスがHub.Contextプロパティとして公開される。
-
| プロパティ | 説明 |
|---|---|
Context.ConnectionId |
クライアントのコネクション ID |
Context.Headers |
HTTP リクエスト・ヘッダーのコレクション |
Context.QueryString |
クエリ文字列のコレクション |
Context.Request |
今回のリクエスト情報 |
Context.RequestCookies |
クッキーのコレクション |
Context.User |
ログイン中のユーザー情報 |
補足: ConnectionId は接続ごとに変わる(再接続で別の値になる)ため、 ユーザの識別子として使ってはならない。 特定ユーザに送信したい場合は
Clients.User(userId)を使うか、 ユーザ ID をキーにしたグループを作る。
グループ管理を行う。
| # | メソッド | 説明 |
|---|---|---|
| 1 |
Groups.Add メソッド |
接続をグループに追加する |
| 2 |
Groups.Remove メソッド |
接続をグループから除外する |
移行メモ(正誤): 元ページの表は
Groups.Addを「全てのクライアント」、Groups.Removeを「自分のみのクライアント」と説明していたが、 これは直後のClientsの表の説明が誤って複写されたものである。Groups.Add/Groups.Removeは 指定した接続 ID をグループに出し入れするメソッドである。
全て、自分、自分以外のクライアントへのメッセージ送信
| # | プロパティのメソッド | 説明 |
|---|---|---|
| 1 |
Clients.All プロパティのメソッド |
全てのクライアント |
| 2 |
Clients.Caller プロパティのメソッド |
自分のみのクライアント |
| 3 |
Clients.Others プロパティのメソッド |
自分以外の全てのクライアント |
グループのクライアントへのメッセージ送信
| # | プロパティのメソッド | 説明 |
|---|---|---|
| 1 |
Clients.Group(string groupName) のメソッド |
指定したグループ名に属するクライアント |
SignalR のバージョン 1.0 から「HubPipeline」と呼ばれる仕組みが追加された。
- ASP.NET MVC のアクション・フィルタのようにメソッドが実行の前・後で
独自の処理を行える。 - 実体は
IHubPipelineModuleインターフェイスを実装したクラスの集合 -
IHubPipelineModuleインターフェイスを実装したクラスの
BeforeとAfterメソッドを実装する。 -
Application_StartでGlobalHost.HubPipeline.AddModuleを使用して
Module を登録する。
- ASP.NET MVC や Web API のように
Authorize属性を付けるだけで認証が可能 - Notify メッセージが送信されるのは認証済みのクライアントだけとなる。
補足: WebSocket はブラウザの仕様上 カスタム ヘッダを付けられないため、 SignalR ではアクセス トークンをクエリ文字列で渡す仕組みになっている (
access_tokenパラメータ)。 クエリ文字列はアクセス ログに残りやすいので、 短命なトークンを使うこと。 なお、CORS (Cross-Origin Resource Sharing) は WebSocket には適用されない(Origin を自前で検証する必要がある)。
- スケールアウトの際は、メッセージング・サーバを用意する必要がある。
- SignalR 1.1 からはスケールアウトに必要な機能が内部的に共通化された。
| 方式 | 内容 |
|---|---|
| Redis | KVS(Key-Value ストア)。他の KVS に無い Pub/Sub 型のメッセージング・システムを持っている |
| Windows Azure サービス・バス | サーバを用意する必要がないので簡単に開始できる。メッセージ量が増えるとスケールしなくなる |
| SQL Server | 「クエリ通知」という機構を利用している。Azure の SQL データベースでは実行できない |
補足: そもそもスケールアウトが必要になる理由は、 接続がサーバに固定されるためである。 サーバ A に繋がっているクライアントへ サーバ B から送信するには、バックプレーンが要る。
ロード バランサ側でも スティッキー セッション(セッション アフィニティ) が必要になる (ASP.NET Core SignalR では、 WebSocket 以外のトランスポートを使う場合に必須)。 これらを避けたい場合は Azure SignalR Service を使う。
-
テンプレートを選択
-
NuGet を使って SignalR をインストール
-
Global.asax.csファイルのApplication_Startで設定-
Hub クラスのルーティングを設定する。
-
必要に応じてスケールアウトに関する設定を行う。
GlobalHost.DependencyResolver.XXXX(config);
-
必要に応じて HubPipeline を追加する設定をする。
GlobalHost.HubPipeline.AddModule(new XXXXHubPipeline());
-
-
通例的に Hubs ディレクトリを作成
-
Hub クラスを作成(なるべく
HubName属性を付与) -
Hub クラスのメソッドに、
Clientsのプロパティを使用してレスポンス処理を書く。
- サーバとの接続オブジェクトを作成
- Hub のプロキシ・オブジェクトを作成
- クライアントのメソッド(コールバック)を登録
- 接続を開始
- サーバのメソッドを呼出
- Windows Server 2012 から搭載された IIS 8 と .NET Framework 4.5 が必要。
- サーバ並びにブラウザ共に WebSocket をサポートしていた場合に有効になる。
- WebSocket がサポートされない場合、
WebSocket 以外の選択肢を用いてリアルタイム通信を実現する。
サーバの要件とブラウザ側の対応状況に基づいて、
選択肢の中から最適な通信手段を SignalR が選択する。
- iframe(Forever Frame)
- Comet (Ajax Long-polling)
- Server-Sent Events
詳しくは、WebSocket を参照。
- WebSocket
- WebAPI
- ASP.NET Core SignalR の概要 - Microsoft Learn
- ASP.NET SignalR - Microsoft Learn
- Microsoft ASP.NET SignalR - Wikipedia
- 特集:ASP.NET SignalR入門 - @IT
Tags: .NET開発, OWIN, ASP.NET, ASP.NET SignalR
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。