web-dev-qa-db-ja.com

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

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

Http Polling: XmlHttpRequestを使用して基本的にAJAX。

Httpロングポーリング: AJAXただし、サーバーが更新を行わない限り、サーバーは応答を保持します。サーバーが更新を取得するとすぐに、サーバーは更新を送信してから、クライアントは別のリクエストを送信できますが、デメリットは追加のヘッダーデータであり、このヘッダーデータをやり取りする必要があるため、追加のオーバーヘッドが発生します。

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

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

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

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

私が見逃している他の重要な違いはありますか?すでにSOにある多くの質問を1つの質問に再質問または結合している場合は申し訳ありませんが、そこにあるすべての情報を完全に理解したいだけです。 on SOおよびこれらの概念に関するウェブ。

ありがとう!

107
Software Guy

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

二重/方向:

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

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

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

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

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

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

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

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

  • プラグインネットワーキング:初期ポリシー要求を除き、フラッシュソケットは未加工です
  • WebSockets:接続セットアップハンドシェイクとフレームあたり数バイト
  • HTTPストリーミング(サーバー接続の再利用)
  • HTTPロングポール:すべてのメッセージの接続
  • HTTPポーリング:すべてのメッセージの接続+データメッセージなし

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

  • WebSocket:iOS 4.2以降。いくつかのAndroid Flashエミュレーション経由、または Firefox for Android または Google Chrome for Android ネイティブWebSocketサポート。
  • プラグインネットワーキング:一部のAndroid。 iOSではない
  • HTTP *:ほとんどはい

Javascriptの使用の複雑さ(最も単純なものから最も複雑なものまで)。確かに複雑さの尺度は多少主観的です。

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

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

83
kanaka

多くの分野をカバーする他の人からのいくつかの素晴らしい答え。もう少し追加します。

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メッセージ分のデータが受信されるまで、クライアントアプリケーションがデータを受信しない可能性があります。それはあまりにもリアルタイムではありません。

WebSocketが利用できない場合、HTTPストリーミングは実行可能な代替手段になりますが、万能薬ではありません。現実世界の状況でWebの悪地で堅牢な方法で作業するには、十分な理解が必要です。

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

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

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

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

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

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

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

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

すでにSOにある質問の多くを再質問または組み合わせて1つの質問にした場合、申し訳ありませんが、SOおよびこれらの概念に関するウェブ。

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

13

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

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

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

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

したがって、クライアント#1は http://example.com/images/logo.gif を要求します。その要求はプロキシを経由して中央のWebサーバーに到達し、logo.gifを提供します。 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、およびビジネスロジックに焦点を当てる必要があるときに、必要のないことを気にしなければならないことを意味します。

10

HTTPは、クライアントとサーバーとの接続数を2に制限します(ただし、これはサブドメインを使用して軽減できます)。IEはこれを積極的に実施することが知られています。FirefoxおよびChromeより多くを許可します(頭の上部の正確な数は覚えていませんが)。これは大きな問題とは思えないかもしれませんが、リアルタイム更新に常に1つの接続を使用している場合、要求は他のHTTP接続を介してボトルネックになる必要があり、クライアントからの接続を開いておくと、サーバーにより多くの負荷がかかるという問題があります。

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

4
TheJuice