SignalR 入門

作成者: Patrick Fletcher

警告

このドキュメントは、SignalR の最新バージョン用ではありません。 SignalR の ASP.NET Coreを見てみましょう。

この記事では、SignalR とは何か、および作成するように設計されたソリューションの一部について説明します。

質問とコメント

このチュートリアルが気に入った方法と、ページの下部にあるコメントで改善できる内容に関するフィードバックをお寄せください。 チュートリアルに直接関連しない質問がある場合は、 ASP.NET SignalR フォーラム または StackOverflow.com に投稿できます。

SignalR とは

ASP.NET SignalR は、リアルタイム Web 機能をアプリケーションに追加するプロセスを簡略化する ASP.NET 開発者向けのライブラリです。 リアルタイム Web 機能は、クライアントが新しいデータを要求するのをサーバーが待機するのではなく、接続されたクライアントにすぐにコンテンツをプッシュする機能です。

SignalR を使用すると、ASP.NET アプリケーションにあらゆる種類の "リアルタイム" Web 機能を追加できます。 チャットは多くの場合、例として使用されますが、さらに多くのことを行うことができます。 ユーザーが Web ページを更新して新しいデータを表示したり、ページが新しいデータを取得するための 長いポーリング を実装したりするたびに、SignalR を使用する候補になります。 たとえば、ダッシュボードと監視アプリケーション、共同作業アプリケーション (ドキュメントの同時編集など)、ジョブの進行状況の更新、リアルタイム フォームなどがあります。

SignalR では、リアルタイム ゲームなど、サーバーからの高頻度更新を必要とする、まったく新しい種類の Web アプリケーションも可能になります。

SignalR は、サーバー側の .NET コードからクライアント ブラウザー (およびその他のクライアント プラットフォーム) で JavaScript 関数を呼び出すサーバー間リモート プロシージャ コール (RPC) を作成するための簡単な API を提供します。 SignalR には、接続管理 (接続イベントや切断イベントなど)、接続のグループ化のための API も含まれています。

SignalR を使用したメソッドの呼び出し

SignalR では、自動的に接続管理が処理され、ユーザーは、チャットルームのように、同時に接続されているすべてのクライアントにメッセージをブロードキャストすることができます。 また、特定のクライアントにメッセージを送信することもできます。 クライアントとサーバー間の接続は、通信ごとに再確立される従来の HTTP 接続とは異なり、永続的なものです。

SignalR では、現在 Web 上で一般的な要求/応答モデルではなく、リモート プロシージャ コール (RPC) を使用してサーバー コードをブラウザーでクライアント コードに呼び出すことができる "サーバー プッシュ" 機能がサポートされています。

SignalR アプリケーションは、組み込みのサードパーティのスケールアウト プロバイダーを使用して、何千ものクライアントにスケールアウトできます。

組み込みプロバイダーには、次のものが含まれます。

サード パーティのプロバイダーには、次のものが含まれます。

SignalR はオープンソースであり、 GitHub からアクセスできます。

SignalR と WebSocket

SignalR は、使用可能な新しい WebSocket トランスポートを使用し、必要に応じて古いトランスポートにフォールバックします。 WebSocket を直接使用してアプリを作成することもできますが、SignalR を使用すると、実装する必要がある追加機能の多くが既に行われています。 最も重要なのは、古いクライアント用に別のコード パスを作成することを心配することなく、WebSocket を利用するようにアプリをコーディングできることを意味します。 SignalR では、基になるトランスポートの変更をサポートするように SignalR が更新されるため、WebSocket の更新について心配する必要もなくなりました。そのため、アプリケーションは WebSocket のバージョン間で一貫したインターフェイスを提供します。

トランスポートとフォールバック

SignalR は、クライアントとサーバーの間でリアルタイムの作業を行うために必要なトランスポートの一部を抽象化したものです。 SignalR は、可能であれば、まず WebSocket 接続の確立を試みます。 WebSocket は SignalR に最適なトランスポートです。これは、次のためです。

  • サーバー メモリの最も効率的な使用。
  • 最も短い待機時間。
  • クライアントとサーバー間の全二重通信など、最も基になる機能。
  • 最も厳しい要件である WebSocket には、次のサーバーが必要です。
    • Windows Server 2012 または Windows 8 で実行します。
    • .NET Framework 4.5。

これらの要件が満たされていない場合、SignalR は他のトランスポートを使用してその接続を行おうとします。

HTML 5 トランスポート

これらのトランスポートは、 HTML 5 のサポートに依存します。 クライアント ブラウザーが HTML 5 標準をサポートしていない場合は、古いトランスポートが使用されます。

  • WebSocket (サーバーとブラウザーの両方が Websocket をサポートできることを示している場合)。 WebSocket は、クライアントとサーバー間の真の永続的な双方向接続を確立する唯一のトランスポートです。 ただし、WebSocket には最も厳しい要件もあります。Microsoft Internet エクスプローラー、Google Chrome、Mozilla Firefox の最新バージョンでのみ完全にサポートされており、Opera や Safari などの他のブラウザーでのみ部分的に実装されています。
  • サーバー送信イベント (EventSource とも呼ばれます) (ブラウザーがサーバー送信イベントをサポートしている場合は、基本的にインターネット エクスプローラーを除くすべてのブラウザーです)。

コメットトランスポート

次のトランスポートは 、Comet Web アプリケーション モデルに基づいています。このモデルでは、ブラウザーまたは他のクライアントが長期の HTTP 要求を保持します。この HTTP 要求は、クライアントが特に要求することなく、サーバーがクライアントにデータをプッシュするために使用できます。

  • Forever Frame (インターネット エクスプローラーのみ)。 Forever Frame は、完了していないサーバー上のエンドポイントに対して要求を行う非表示の IFrame を作成します。 その後、サーバーはスクリプトをクライアントに継続的に送信し、すぐに実行され、サーバーからクライアントへの一方向のリアルタイム接続が提供されます。 クライアントからサーバーへの接続では、サーバーからクライアントへの接続とは別の接続が使用されます。標準の HTTP 要求と同様に、送信する必要があるデータごとに新しい接続が作成されます。
  • Ajax の長いポーリング。 長いポーリングでは永続的な接続は作成されませんが、代わりに、サーバーが応答するまで開いたままの要求でサーバーをポーリングし、その時点で接続が閉じられ、新しい接続がすぐに要求されます。 これにより、接続のリセット中に待機時間が発生する可能性があります。

どの構成でサポートされるトランスポートの詳細については、「 サポートされているプラットフォーム」を参照してください。

トランスポート選択プロセス

次の一覧は、SignalR が使用するトランスポートを決定するために使用する手順を示しています。

  1. ブラウザーがインターネット エクスプローラー 8 以前の場合は、長いポーリングが使用されます。

  2. JSONP が構成されている場合 (つまり、 jsonp 接続の開始時に パラメーターが に true 設定されます)、長いポーリングが使用されます。

  3. クロスドメイン接続が行われている場合 (つまり、SignalR エンドポイントがホスティング ページと同じドメインにない場合)、次の条件が満たされた場合は WebSocket が使用されます。

    • クライアントは CORS (クロスオリジン リソース共有) をサポートしています。 CORS をサポートするクライアントの詳細については、 caniuse.com の CORS に関するページを参照してください。

    • クライアントは WebSocket をサポートしています

    • サーバーは WebSocket をサポートしています

      これらの条件のいずれかが満たされない場合は、長いポーリングが使用されます。 クロスドメイン接続の詳細については、「クロス ドメイン接続を確立する方法」を参照してください。

  4. JSONP が構成されておらず、接続がクロスドメインでない場合、クライアントとサーバーの両方でサポートされている場合は WebSocket が使用されます。

  5. クライアントまたはサーバーが WebSocket をサポートしていない場合は、使用可能な場合はサーバー送信イベントが使用されます。

  6. サーバー送信イベントが使用できない場合は、Forever Frame が試行されます。

  7. Forever Frame が失敗した場合は、長いポーリングが使用されます。

トランスポートの監視

ハブでログを有効にし、ブラウザーでコンソール ウィンドウを開くと、アプリケーションで使用しているトランスポートを確認できます。

ブラウザーでハブのイベントのログ記録を有効にするには、クライアント アプリケーションに次のコマンドを追加します。

$.connection.hub.logging = true;

  • インターネット エクスプローラーで、F12 キーを押して開発者ツールを開き、[コンソール] タブをクリックします。

    Microsoft Internet エクスプローラー のコンソール

  • Chrome で、Ctrl + Shift + J キーを押してコンソールを開きます。

    Google Chrome のコンソール

コンソールを開いてログ記録を有効にすると、SignalR で使用されているトランスポートを確認できます。

WebSocket トランスポートを示すインターネット エクスプローラーのコンソール

トランスポートの指定

トランスポートのネゴシエートには、一定の時間とクライアント/サーバー リソースが必要です。 クライアント機能がわかっている場合は、クライアント接続の開始時にトランスポートを指定できます。 次のコード スニペットは、クライアントが他のプロトコルをサポートしていないことがわかっている場合に使用されるように、Ajax Long Polling トランスポートを使用して接続を開始する方法を示しています。

connection.start({ transport: 'longPolling' });

クライアントが特定のトランスポートを順番に試す場合は、フォールバック注文を指定できます。 次のコード スニペットは、WebSocket を試して失敗し、ロング ポーリングに直接移動する方法を示しています。

connection.start({ transport: ['webSockets','longPolling'] });

トランスポートを指定するための文字列定数は、次のように定義されます。

  • webSockets
  • foreverFrame
  • serverSentEvents
  • longPolling

接続とハブ

SignalR API には、クライアントとサーバーの間で通信するための 2 つのモデル (永続的な接続とハブ) が含まれています。

Connection は、単一受信者、グループ化、またはブロードキャスト メッセージを送信するための単純なエンドポイントを表します。 Persistent Connection API (PersistentConnection クラスによって .NET コードで表されます) を使用すると、開発者は SignalR が公開する低レベルの通信プロトコルに直接アクセスできます。 接続通信モデルの使用は、Windows Communication Foundation などの接続ベースの API を使用した開発者にはなじみがあります。

ハブは、接続 API に基づいて構築されたより高度なパイプラインであり、クライアントとサーバーが互いに直接メソッドを呼び出すことができます。 SignalR は、マジックのようにマシン境界を越えたディスパッチを処理し、クライアントはローカル メソッドと同じくらい簡単にサーバー上のメソッドを呼び出すことができます。その逆も可能です。 ハブ通信モデルの使用は、.NET リモート処理などのリモート呼び出し API を使用した開発者にはなじみがあります。 ハブを使用すると、厳密に型指定されたパラメーターをメソッドに渡して、モデル バインドを有効にすることもできます。

アーキテクチャの図

次の図は、ハブ、永続的な接続、およびトランスポートに使用される基になるテクノロジの間の関係を示しています。

API、トランスポート、およびクライアントを示す SignalR アーキテクチャ図

ハブのしくみ

サーバー側コードがクライアントでメソッドを呼び出すと、呼び出されるメソッドの名前とパラメーターを含むアクティブなトランスポートを介してパケットが送信されます (オブジェクトがメソッド パラメーターとして送信されると、JSON を使用してシリアル化されます)。 その後、クライアントはメソッド名をクライアント側コードで定義されているメソッドと一致します。 一致する場合、逆シリアル化されたパラメーター データを使用してクライアント メソッドが実行されます。

メソッド呼び出しは、 Fiddler などのツールを使用して監視できます。次の図は、Fiddler の [ログ] ウィンドウで SignalR サーバーから Web ブラウザー クライアントに送信されるメソッド呼び出しを示しています。 メソッド呼び出しは と呼ばれる MoveShapeHubハブから送信され、呼び出されるメソッドは と呼ばれます updateShape

SignalR トラフィックを示す Fiddler ログの表示

この例では、ハブ名は パラメーターで H 識別されます。メソッド名は パラメーターで M 識別され、メソッドに送信されるデータは パラメーターで A 識別されます。 このメッセージを生成したアプリケーションは、 高頻度リアルタイム チュートリアルで作成されます。

コミュニケーション モデルの選択

ほとんどのアプリケーションでは、Hubs API を使用する必要があります。 Connections API は、次の状況で使用できます。

  • 送信される実際のメッセージの形式を指定する必要があります。
  • 開発者は、リモート呼び出しモデルではなく、メッセージングおよびディスパッチ モデルを使用することを好みます。
  • SignalR を使用するために、メッセージング モデルを使用する既存のアプリケーションが移植されています。