HTTPポーリング、ロングポーリング、HTTPストリーミング、およびWebSocketについての私の理解


122

質問タイトルのキーワードについて、SOとWebに関する多くの投稿を読み、それらから多くのことを学びました。私が読んだ質問のいくつかは特定の実装の課題に関連しており、他の質問は一般的な概念に焦点を当てています。すべての概念とテクノロジーXがテクノロジーYよりも発明された理由などを確実に理解したいだけです。だからここに行く:

HTTPポーリング:基本的にAJAX、XmlHttpRequestを使用。

HTTPロングポーリング: AJAXですが、サーバーに更新がない限り、サーバーは応答を保持します。サーバーが更新を取得するとすぐに、サーバーはそれを送信し、クライアントは別の要求を送信できます。不利な点は、前後に送信する必要がある追加のヘッダーデータが原因で追加のオーバーヘッドが発生することです。

Httpストリーミング:ロングポーリングに似ていますが、サーバーは「Transfer Encoding:chunked」のヘッダーで応答するため、サーバーがデータを送信するたびに新しいリクエストを開始する必要はありません(したがって、追加のヘッダーオーバーヘッドを節約できます)。ここでの欠点は、サーバーから送信された複数のチャンクを区別するために、データの構造を「理解」して理解する必要があることです。

Javaアプレット、Flash、Silverlight: tcp / ipを介してソケットサーバーに接続する機能を提供しますが、プラグインであるため、開発者はそれらに依存したくありません。

WebSockets:これらは、上記のメソッドの短所を次のように解決しようとする新しいAPIです。

  • Javaアプレット、Flash、Silverlightなどのプラグインに対するWebSocketの唯一の利点は、WebSocketがブラウザにネイティブに組み込まれており、プラグインに依存しないことです。
  • HTTPストリーミングに対するWebSocketの唯一の利点は、受信したデータを「理解」して解析するための努力をする必要がないことです。
  • ロングポーリングに対するWebSocketsの唯一の利点は、余分なヘッダーサイズを排除し、リクエスト用のソケット接続を開閉することです。

私が見逃している他の重要な違いはありますか?既にSOに関する質問の多くを1つの質問に再質問または組み合わせている場合は申し訳ありませんが、これらの概念に関してSOおよびWebにあるすべての情報から完全に理解したいと思います。

ありがとう!


4
サーバー送信イベントは、双方向通信が不要な場合にも注目する価値があります。
レゲッター2012

これは本当に役立つ質問です。複数の著者が貢献できる1つの回答があった場合、それは潜在的にさらに役立つと思います。
レゲッター2012

@leggetterありがとうPhil、サーバー送信イベントに関するヒントをありがとう。双方向通信のシナリオについて学びたいです。ありがとう。
Software Guy

1
HTTPストリーミングとロングポーリングでは、双方向通信のために2番目の接続が必要です。サーバー->クライアントの「プッシュ」通信のための1つのより長く存続する接続と、クライアント->サーバーの通信のための2番目の短命な接続。この2番目の接続は、データへのサブスクリプションのセットアップや変更などを行うために使用されます。したがって、EventSourceは双方向ソリューションで使用でき、実際にはHTTPストリーミングとロングポーリングから生まれた標準化されたソリューションです。
レゲッター2012

1
:あなたはまた、私が書いた技術のこの分類をチェックアウトする場合がありますstackoverflow.com/questions/12078550/...
アレッサンドロAlinone

回答:


92

あなたが特定したものよりも多くの違いがあります。

両面/方向:

  • 単方向:HTTPポーリング、ロングポーリング、ストリーミング。
  • 双方向:WebSockets、プラグインネットワーク

レイテンシーの増加順(概算):

  • WebSocket
  • プラグインネットワーク
  • HTTPストリーミング
  • HTTPロングポール
  • HTTPポーリング

CORS(クロスオリジンサポート):

  • WebSockets:はい
  • プラグインネットワーキング:ポリシーリクエストによるFlash(他については不明)
  • HTTP *(最近のサポート)

ネイティブバイナリデータ(型付き配列、blob):

  • WebSockets:はい
  • プラグインネットワーキング:Flashなし(ExternalInterface全体でURLエンコーディングが必要)
  • HTTP *:バイナリ型のサポートを有効にするための最近の提案

効率の低下における帯域幅:

  • プラグインネットワーク:最初のポリシーリクエストを除いて、フラッシュソケットは未加工です
  • WebSockets:接続設定ハンドシェイクおよびフレームあたり数バイト
  • HTTPストリーミング(サーバー接続の再利用)
  • HTTP long-poll:すべてのメッセージの接続
  • HTTPポーリング:すべてのメッセージの接続+データメッセージなし

モバイルデバイスのサポート:

  • WebSocket:iOS 4.2以降。一部のAndroidは、Flashエミュレーションを介して、またはFirefox(Android)またはGoogle Chrome(Android)を使用しており、どちらもネイティブのWebSocketサポートを提供します。
  • プラグインネットワーク:一部のAndroid。iOSではない
  • HTTP *:ほとんどはい

JavaScriptの使用法の複雑さ(最も単純なものから最も複雑なものまで)。確かに、複雑さの測定はやや主観的です。

  • WebSocket
  • HTTPポーリング
  • プラグインネットワーク
  • HTTPロングポーリング、ストリーミング

また、Server-Sent Eventsと呼ばれるHTTPストリーミングを標準化するためのW3C提案があることに注意してください。それは現在、その進化のかなり早い段階であり、WebSocketに匹敵する単純さを備えた標準のJavaScript APIを提供するように設計されています。


1
素敵な返事のカナカに感謝します。理由/ httpストリーミングの遅延がWebソケットよりも高い理由を教えてください。多分簡単な例で?どうもありがとう。
Software Guy

2
@SoftwareGuy。多くの理由。最近のブラウザーでは、XMLHTTPRequest onprogressイベントハンドラーを使用してデータを通知できます。しかし、仕様によると、50msは最小の通知間隔です。それ以外の場合は、応答データをポーリングする必要があります。また、クライアント送信は新しいHTTP接続を確立するため、往復の待ち時間が大幅に増加します。また、多くのWebサーバーは30秒程度でHTTP接続を切断するため、サーバープッシュ接続を再確立し続ける必要があることがよくあります。ローカルネットワークで5〜10ミリ秒のWebSocketラウンドトリップレイテンシを確認しました。HTTPストリーミングの待ち時間は、おそらく50ミリ秒以上です。
kanaka 2012

詳細な返信をありがとう:)
Software Guy

1
@leggetterありがとうフィル、httpストリーミング経由でクライアントからサーバーにデータを送信するとオーバーヘッドが発生することを意味しますか?新しい接続を開かなくても、httpストリーミングでサーバーにデータを送信することは可能ですか?ありがとう。
Software Guy

1
@ネイサンは、優れた修士論文プロジェクトのように聞こえます!確かに、ポーリングはシステムをイベント駆動型モデルよりも使用頻度の高い状態に保ちますが、正確にどの程度の電力節約ができるかは、さまざまな規模でかなり大規模な経験的テストが必要になるでしょう。
カナカ

13

多くの根拠をカバーする他の人からのいくつかの素晴らしい答え。ここで少し余分です。

Javaアプレット、Flash、Silverlightなどのプラグインに対するWebSocketの唯一の利点は、WebSocketがブラウザにネイティブに組み込まれており、プラグインに依存しないことです。

これにより、Javaアプレット、Flash、またはSilverlightを使用してソケット接続を確立できる場合は、可能です。ただし、制限があるため、現実の世界であまり頻繁に展開されることはありません。

たとえば、仲介者はそのトラフィックをシャットダウンできます。WebSocket標準は、既存のHTTPインフラストラクチャと互換性があるように設計されているため、ファイアウォールやプロキシなどの仲介者による干渉を受けにくくなっています。

さらに、WebSocketは、専用のポートを必要とせずにポート80および443を使用できます。これも、既存のHTTPインフラストラクチャと可能な限り互換性のあるプロトコル設計のおかげです。

これらの代替ソケット(Java、Flash、Silverlight)をクロスオリジンアーキテクチャで安全に使用することは困難です。したがって、クロスオリジンを使用しようとする人々は、安全にそれを行う努力に行くのではなく、不安を許容します。

また、追加の「非標準」ポートを開く(管理者が嫌いなことを行う)か、管理する必要のあるポリシーファイルを要求することもできます。

つまり、ソケット接続にJava、Flash、Silverlightを使用することには問題があり、深刻なアーキテクチャーにデプロイされることがあまりありません。FlashとJavaは、おそらく少なくとも10年間この機能を持っていましたが、まだ普及していません。

WebSocket標準は、これらの制限を念頭に置き、うまくいけばそれらからいくつかの教訓を学んだことで、新しいアプローチから始めることができました。

一部のWebSocket実装では、WebSocket接続を確立できない場合(古いブラウザーで実行している場合や、仲介者が干渉している場合など)のフォールバックとしてFlash(またはSilverlightやJava)を使用しています。

これらの状況に対するある種のフォールバック戦略は賢いですが、必要な場合でも、Flashなどを使用するもののほとんどは、上記の欠点に悩まされます。それはそうである必要はありません-Flash、Silverlightなどを使用して安全なクロスオリジン対応接続を実現するための回避策があります-しかし、ほとんどの実装は簡単ではないのでそれを行いません。

たとえば、クロスオリジン接続をWebSocketに依存している場合は、問題なく動作します。しかし、古いブラウザで実行したり、ファイアウォールやプロキシが干渉してFlashに依存したりすると、フォールバックとして、同じクロスオリジン接続を行うのが難しくなります。もちろん、セキュリティを気にしない限り。

つまり、かなりの作業を行う準備ができているか、それをうまく行ったフレームワークを使用する準備ができていない限り、ネイティブ接続と非ネイティブ接続で機能する単一の統合アーキテクチャを持つことは困難です。理想的なアーキテクチャでは、接続がネイティブであるかどうかに気付かないでしょう。セキュリティ設定はどちらの場合でも機能します。クラスタリング設定は引き続き機能します。キャパシティプランニングは引き続き有効です。等々。

HTTPストリーミングに対するWebSocketの唯一の利点は、受信したデータを「理解」して解析するための努力をする必要がないことです。

データが数分、数時間、またはそれ以上流れるようにHTTPストリームを開いて座っているほど簡単ではありません。クライアントが異なると動作も異なり、管理する必要があります。たとえば、一部のクライアントはデータをバッファに格納し、しきい値に達するまでアプリケーションにリリースしません。さらに悪いことに、一部は接続が閉じられるまでアプリケーションにデータを渡さないでしょう。

したがって、複数のメッセージをクライアントに送信する場合、たとえば、50メッセージ分のデータが受信されるまで、クライアントアプリケーションがデータを受信しない可能性があります。それはあまりにもリアルタイムではありません。

HTTPストリーミングは、WebSocketが利用できない場合の実行可能な代替手段となり得ますが、万能薬ではありません。現実世界の状況でWebの荒れ地で確実に機能するためには、十分な理解が必要です。

私が見逃している他の重要な違いはありますか?

まだ誰も言及していないことがもう1つあるので、それを取り上げます。

WebSocketプロトコルは、上位レベルのプロトコルのトランスポート層になるように設計されました。WebSocket接続を介してJSONメッセージなどを直接送信できますが、標準またはカスタムのプロトコルを伝送することもできます。

たとえば、人々が既に行っているように、WebSocket経由でAMQPまたはXMPPを実行できます。したがって、クライアントは、ブローカー自体に直接接続されているかのように(場合によっては接続されている)、AMQPブローカーからメッセージを受信できます。

または、カスタムプロトコルを備えた既存のサーバーがある場合は、それをWebSocket経由で転送して、そのバックエンドサーバーをWebに拡張できます。多くの場合、企業内でロックされている既存のアプリケーションは、バックエンドインフラストラクチャを変更することなく、WebSocketを使用してその範囲を広げることができます。

(当然、すべてを安全に実行できるようにしたいので、ベンダーまたはWebSocketプロバイダーに確認してください。)

一部の人々はWebSocketをWebのTCPと呼んでいます。TCPが上位レベルのプロトコルを転送するのと同じように、WebSocketも転送するため、Webインフラストラクチャと互換性があります。

したがって、JSON(またはその他の)メッセージをWebSocket経由で直接送信することは常に可能ですが、既存のプロトコルも検討する必要があります。あなたがしたいことがたくさんあるので、おそらくそれをするためにすでに考えられているプロトコルがあるでしょう。

既にSOに関する質問の多くを1つの質問に再質問または組み合わせている場合は申し訳ありませんが、これらの概念に関してSOおよびWebにあるすべての情報から完全に理解したいと思います。

これは素晴らしい質問でした、そして答えはすべて非常に有益でした!


優れたヘルプと情報を提供してくれたロビンに感謝します。もう1つ質問があります。httpストリーミングもプロキシによってキャッシュされるのに、Webソケットはキャッシュされないという記事に出くわしました。どういう意味ですか?
Software Guy

:StackOverflowの応答コメントでサイズを制限しているので、私は以下の私の答え与えてくれた stackoverflow.com/questions/12555043/...
ロビン・ツィンマーマン

@RobinZimmermann、あなたの答えは私のお気に入りです。本当に良い詳細な回答の+1。
securecurve

10

さらに1つ質問があります。httpストリーミングもプロキシによってキャッシュされるのに対し、Webソケットはキャッシュされないという記事に出くわしました。どういう意味ですか?

(StackOverflowはコメント応答のサイズを制限するため、インラインではなく、ここで応答する必要がありました。)

それは良い点です。これを理解するために、従来のHTTPシナリオについて考えてみましょう... たとえば、ブラウザがWebページを開いて、http://example.comを要求するとします。サーバーは、ページのHTMLを含むHTTPで応答します。次に、ブラウザーはページにリソースがあることを認識するため、CSSファイル、JavaScriptファイル、および画像のリクエストを開始します。それらはすべて静的ファイルであり、それらを要求するすべてのクライアントで同じになります。

一部のプロキシは静的リソースをキャッシュするため、他のクライアントからの後続のリクエストは、中央のWebサーバーに戻ってそれらを取得する必要がなく、プロキシから静的リソースを取得できます。これはキャッシングであり、リクエストと処理を中央サービスからオフロードするための優れた戦略です。

つまり、クライアント#1がhttp://example.com/images/logo.gifをリクエストするとします。このリクエストは、プロキシを経由して、logo.gifを提供する中央のWebサーバーに到達します。logo.gifがプロキシを通過すると、プロキシはその画像を保存し、アドレスhttp://example.com/images/logo.gifに関連付けます。

クライアント#2がやって来てhttp://example.com/images/logo.gifもリクエストすると、プロキシは画像を返すことができ、センターのWebサーバーに通信する必要はありません。これにより、エンドユーザーへの応答が速くなります。これは常に優れていますが、センターへの負荷が少ないことも意味します。これは、ハードウェアコストの削減、ネットワークコストの削減などにつながります。したがって、それは良いことです。

この問題は、logo.gifがWebサーバーで更新されるときに発生します。プロキシは、新しいイメージがあることを認識せずに、引き続き古いイメージを提供します。これにより、有効期限の全体につながるため、プロキシはイメージが「期限切れ」になる前に短時間のみキャッシュし、次のリクエストはプロキシを経由してWebサーバーに送信され、プロキシのキャッシュが更新されます。中央サーバーが既知のキャッシュなどにプッシュできる高度なソリューションもあり、物事は非常に洗練されています。

これはあなたの質問にどのように結びついていますか?

サーバーがクライアントにHTTPをストリーミングしているHTTPストリーミングについて質問しました。ただし、ストリーミングHTTPは、データの送信を停止しないことを除いて、通常のHTTPと同じです。Webサーバーが画像を提供する場合、最終的に終了するクライアントにHTTPを送信します。画像全体を送信しました。データを送信する場合もまったく同じですが、サーバーが送信するのは非常に長い間(たとえば、非常に巨大な画像など)、完了しない場合もあります。

プロキシの観点からは、画像などの静的リソースのHTTPと、HTTPストリーミングのデータを区別できません。どちらの場合も、クライアントはサーバーに要求を出しました。プロキシはその要求と応答も記憶していました。次回そのリクエストが来たときに、プロキシは同じレスポンスを提供します。

したがって、クライアントが株価などのリクエストを行い、レスポンスを受け取った場合、次のクライアントが同じリクエストを行い、キャッシュされたデータを取得する場合があります。おそらくあなたが望むものではありません!最新の株価が欲しい株価を請求したら?

だから問題です。

そのような問題を処理するためのトリックと回避策があります、それは本当です。それが今日使用されているので、明らかにHTTPストリーミングを機能させることができます。それはすべてエンドユーザーに透過的ですが、それらのアーキテクチャーを開発して保守する人々は、フープを飛び越えて価格を支払わなければなりません。その結果、アーキテクチャが過度に複雑になり、メンテナンス、ハードウェア、複雑さ、コストが増加します。また、開発者は、アプリケーション、GUI、およびビジネスロジックにのみ焦点を当てる必要がある場合に、不要なことを気にする必要があることが多く、基盤となる通信について心配する必要はありません。


1
素晴らしい詳細ロビン、どうもありがとう!誠にありがとうございました。私はここのすべての素晴らしい人々からすでに多くを学びました!:)
Software Guy

4

HTTPは、クライアントがサーバーと持つことができる接続数を2に制限します(ただし、これはサブドメインを使用することで軽減できます)。IEはこれを熱心に実施することが知られています。FirefoxとChromeではさらに多くのことが可能です(ただし、頭のてっぺんの数は正確には覚えていません)。これは大きな問題のようには見えないかもしれませんが、リアルタイム更新に常に1つの接続を使用している場合、他のすべてのリクエストは他のHTTP接続を介してボトルネックになる必要があります。また、クライアントからのオープンな接続が増えると、サーバーの負荷が大きくなるという問題があります。

WebSocketはTCPベースのプロトコルであるため、このHTTPレベルの接続制限の影響を受けません(もちろん、ブラウザのサポートは均一ではありません)。


ジュースのおかげで、あなたによって強調された複数の同時接続の問題に加えて、ウェブソケットに関する私の残りの仮定は正しいですか?
Software Guy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.