SignalR 入門

投稿者: パトリック・フレッチャー

警告

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

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

質問とコメント

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

SignalR とは

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

SignalR を使用して、任意の種類の "リアルタイム" Web 機能を ASP.NET アプリケーションに追加できます。 チャットは多くの場合、例として使用されますが、さらに多くのことを行うことができます。 ユーザーが 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 Explorer、Google Chrome、Mozilla Firefox の最新バージョンでのみ完全にサポートされており、Opera や Safari などの他のブラウザーでのみ部分的な実装が行われています。
  • サーバー送信イベント (EventSource とも呼ばれます) (ブラウザーがサーバー送信イベントをサポートしている場合、これは基本的に Internet Explorer を除くすべてのブラウザーです)。

Comet トランスポート

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

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

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

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

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

  1. ブラウザーが Internet Explorer 8 以前の場合は、長いポーリングが使用されます。

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

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

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

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

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

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

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

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

  6. サーバー送信イベントを使用できない場合は、永遠のフレームが試行されます。

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

トランスポートの監視

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

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

$.connection.hub.logging = true;

  • Internet Explorer で、F12 キーを押して開発者ツールを開き、[コンソール] タブをクリックします。

    Microsoft Internet Explorer のコンソール

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

    Google Chrome の本体

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

WebSocket トランスポートを示す Internet Explorer のコンソール

トランスポートの指定

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

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

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

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

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

  • webSockets
  • foreverFrame
  • serverSentEvents
  • longPolling

接続とハブ

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

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

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

アーキテクチャの図

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

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

ハブのしくみ

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

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

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

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

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

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

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