WebSocketsプロトコルとHTTP


330

websocketとHTTPについては多くのブログと議論があり、多くの開発者やサイトはwebsocketを強く推奨していますが、それでも理由がわかりません。

たとえば(WebSocket愛好家の議論):

HTML5 Webソケットは、Web通信の次の進化、つまりWeb上の単一のソケットを介して動作する全二重の双方向通信チャネルを表します。(http://www.websocket.org/quantum.html

HTTPはストリーミングをサポートします。リクエストボディストリーミング(大きなファイルをアップロードするときに使用)とレスポンスボディストリーミング。

WebSocketとの接続中に、クライアントとサーバーはフレームごとに2バイトのデータを交換します。これに対して、継続的なポーリングを行うと、8キロバイトのHTTPヘッダーが使用されます。

2バイトにtcpおよびtcpプロトコルのオーバーヘッドが含まれていないのはなぜですか?

GET /about.html HTTP/1.1
Host: example.org

これは〜48バイトのHTTPヘッダーです。

httpチャンクエンコーディング-https : //en.wikipedia.org/wiki/Chunked_transfer_encoding

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
  • したがって、各チャンクごとのオーバーヘッドは大きくありません。

また、どちらのプロトコルもTCPを介して機能するため、長時間の接続に関するすべてのTCPの問題が依然として存在します。

質問:

  1. なぜwebsocketsプロトコルの方が優れているのですか?
  2. なぜhttpプロトコルを更新する代わりに実装されたのですか?

2
あなたの質問は何ですか?
ジョナス

@ジョナス、1)なぜwebsocketsプロトコルが優れているのですか?2)httpプロトコルを更新する代わりになぜ実装されたのですか?3)なぜwebsocketはそれほど促進されているのですか?
4esn0k 2013

@JoachimPileborg、デスクトップアプリケーションではTCPソケットまたはhttpでも実行できます。また、WebRTCを使用してWebサイトのブラウザー間通信を行う必要があります
4esn0k

@JoachimPileborg、これはWebSocketではなく、ブラウザ間のWebRTCです
4esn0k

@ 4esn0k、WSは優れていません。それらはいくつかの特定のタスクでは異なり、優れています。3)これは、人々がWebの新しい可能性を認識し、開拓するための新しい機能です
Jonas

回答:


491

1)なぜWebSocketsプロトコルの方が優れているのですか?

WebSocketは、特にクライアントからサーバーへのメッセージの待ち時間が短い場合に、待ち時間の短い通信が必要な状況に適しています。サーバーからクライアントへのデータの場合、長時間保持される接続とチャンク転送を使用して、レイテンシをかなり低くすることができます。ただし、これは、クライアントからサーバーへのメッセージごとに新しい接続を確立する必要があるクライアントからサーバーへの待ち時間には役立ちません。

48バイトのHTTPハンドシェイクは、多くのヘッダーとCookieデータを含む、要求の一部として(両方向に)数キロバイトのデータが送信されることが多い実際のHTTPブラウザー接続では現実的ではありません。Chromeを使用するためのリクエスト/レスポンスの例を次に示します。

リクエストの例(Cookieデータを含む2800バイト、Cookieデータなしの490バイト):

GET / HTTP/1.1
Host: www.cnn.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.68 Safari/537.17
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: [[[2428 byte of cookie data]]]

応答の例(355バイト):

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 13 Feb 2013 18:56:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: CG=US:TX:Arlington; path=/
Last-Modified: Wed, 13 Feb 2013 18:55:22 GMT
Vary: Accept-Encoding
Cache-Control: max-age=60, private
Expires: Wed, 13 Feb 2013 18:56:54 GMT
Content-Encoding: gzip

HTTPとWebSocketはどちらも同じサイズの初期接続ハンドシェイクを備えていますが、WebSocket接続では初期ハンドシェイクが1回実行され、その後、小さなメッセージのオーバーヘッドは6バイトだけになります(ヘッダーに2、マスク値に4)。レイテンシのオーバーヘッドは、ヘッダーのサイズからではなく、それらのヘッダーを解析/処理/格納するロジックから発生します。さらに、TCP接続セットアップの待ち時間は、各要求のサイズまたは処理時間よりもおそらく大きな要因です。

2)HTTPプロトコルを更新する代わりになぜ実装されたのですか?

SPDYHTTP 2.0QUICなど、HTTPプロトコルを再設計して、パフォーマンスを向上させ、レイテンシを短縮する取り組みがあります。これにより、通常のHTTPリクエストの状況が改善されますが、WebSocketやWebRTC DataChannelは、HTTPプロトコルよりもクライアントからサーバーへのデータ転送のレイテンシが低い可能性があります(または、WebSocketによく似たモードで使用されますいずれかの方法)。

更新

以下は、Webプロトコルについて考えるためのフレームワークです。

  • TCP:低レベル、双方向、全二重、および保証された順序トランスポート層。ブラウザーサポートなし(プラグイン/ Flashを除く)。
  • HTTP 1.0:TCPに階層化された要求/応答トランスポートプロトコル。クライアントは1つの完全な要求を行い、サーバーは1つの完全な応答を返し、接続は閉じられます。要求メソッド(GET、POST、HEAD)には、サーバー上のリソースに対して特定のトランザクション上の意味があります。
  • HTTP 1.1:HTTP 1.0の要求と応答の性質を維持しますが、複数の完全な要求/完全な応答(要求ごとに1つの応答)に対して接続を開いたままにすることができます。リクエストとレスポンスに完全なヘッダーが残っていますが、接続は再利用され、閉じられません。HTTP 1.1では、いくつかの追加の要求メソッド(OPTIONS、PUT、DELETE、TRACE、CONNECT)も追加されました。これらも特定のトランザクション上の意味を持っています。ただし、HTTP 2.0ドラフトプロポーザルの紹介で述べたように、HTTP 1.1パイプラインは広く展開されていないため、ブラウザーとサーバー間の遅延を解決するHTTP 1.1のユーティリティが大幅に制限されます。
  • Long-poll:サーバーがクライアント要求にすぐに応答しない(またはヘッダーで部分的にのみ応答する)HTTP(1.0または1.1のいずれか)に対する一種の「ハッキング」。サーバーの応答後、クライアントはすぐに新しいリクエストを送信します(HTTP 1.1の場合は同じ接続を使用)。
  • HTTPストリーミング:サーバーが単一のクライアント要求に複数の応答を送信できるようにするさまざまな手法(マルチパート/チャンク応答)。W3Cは、これをMIMEタイプを使用したサーバー送信イベントとして標準化していますtext/event-stream。ブラウザーAPI(WebSocket APIとかなり似ています)は、EventSource APIと呼ばれます。
  • コメット/サーバープッシュ:これは、ロングポーリングとHTTPストリーミングの両方を含む包括的な用語です。Cometライブラリは通常、複数の手法をサポートしており、クロスブラウザおよびクロスサーバーのサポートを最大限に活用しています。
  • WebSockets:HTTPフレンドリーなアップグレードハンドシェイクを使用するトランスポート層の組み込みTCP。ストリーミングトランスポートであるTCPとは異なり、WebSocketはメッセージベースのトランスポートです。メッセージはネットワーク上で区切られ、アプリケーションに配信される前に完全に再構成されます。WebSocket接続は、双方向、全二重、長寿命です。最初のハンドシェイク要求/応答の後、トランザクションのセマンティクスはなく、メッセージごとのオーバーヘッドはほとんどありません。クライアントとサーバーはいつでもメッセージを送信でき、メッセージの受信を非同期で処理する必要があります。
  • SPDY:Googleが提案した、より効率的なワイヤプロトコルを使用してHTTPを拡張する提案ですが、すべてのHTTPセマンティクス(要求/応答、Cookie、エンコーディング)を維持しています。SPDYは新しいフレーム形式(長さの接頭辞が付いたフレーム)を導入し、HTTP要求/応答ペアを新しいフレーム層にレイヤー化する方法を指定します。接続が確立された後、ヘッダーを圧縮して新しいヘッダーを送信できます。ブラウザとサーバーには、SPDYの実際の実装があります。
  • HTTP 2.0:SPDYと同様の目標があります。HTTPのセマンティクスを維持しながら、HTTPの待ち時間とオーバーヘッドを削減します。現在のドラフトはSPDYから派生しており、ハンドシェイクとフレーミングに関するWebSocket標準と非常によく似たアップグレードハンドシェイクとデータフレーミングを定義しています。代替HTTP 2.0ドラフトプロポーザル(httpbis-speed-mobility)は実際にトランスポート層にWebSocketを使用し、SPDY多重化とHTTPマッピングをWebSocket拡張として追加します(WebSocket拡張はハンドシェイク中にネゴシエートされます)。
  • WebRTC / CU-WebRTC:ブラウザ間のピアツーピア接続を可能にする提案。基になるトランスポートはTCPではなくSDP /データグラムであるため、これにより、平均遅延および最大遅延の通信が可能になる場合があります。これにより、パケット/メッセージの順不同の配信が可能になり、後続のすべてのパケットの配信を遅らせるドロップされたパケットによって引き起こされる遅延スパイクのTCP問題を回避します(順序どおりの配信を保証するため)。
  • QUIC:TCPよりもWebレイテンシを減らすことを目的とした実験的なプロトコルです。表面的には、QUICはUDPに実装されたTCP + TLS + SPDYによく似ています。QUICは、HTTP / 2と同等の多重化とフロー制御、TLSと同等のセキュリティ、TCPと同等の接続セマンティクス、信頼性、および輻輳制御を提供します。TCPはオペレーティングシステムカーネルとミドルボックスファームウェアに実装されているため、TCPに大幅な変更を加えることはほぼ不可能です。ただし、QUICはUDPの上に構築されているため、そのような制限はありません。QUICは、HTTP / 2セマンティクス用に設計および最適化されています。

参照


1
>>ただし、これは、クライアントからサーバーへのメッセージごとに新しい接続を確立する必要があるクライアントからサーバーへの待ち時間には役立ちません。-レスポンスボディのストリーミングはどうですか?XMLHttpRequest APIはこれを許可していませんが、存在しています。サーバーへのストリーミングでは、クライアント側からストリーミングできます。
4esn0k 2013

8
@フィリップ、彼は私がとにかく徹底的に研究して文書化したいと思っていた質問をしました。WebSocketと他のHTTPベースのメカニズムの問題はかなり頻繁に出てきますが、リンクへの適切な参照があります。しかし、はい、おそらく質問者は答えを選択したり賞金を受け取ったりしなかったので、WebSocketsとHTTPに関する先入観を裏付ける証拠を探していたようです。
カナカ2013

9
プロトコルのこの非常に素晴らしく正確な概要をありがとうございました。
Martin Meeser、2014

2
@WardC caniuse.comは、ブラウザーの互換性情報(モバイルを含む)を提供します。
カナカ2015

3
@ www139、いいえ、WebSocketプロトコルレベルでは、一方または他方が接続を閉じるまで、接続は開いたままです。また、TCPタイムアウト(TCPベースのプロトコルの問題)を心配する必要があるかもしれませんが、1分または2分ごとにあらゆる種類のトラフィックが発生すると、接続は開いたままになります。実際、WebSocketプロトコル定義はping / pongフレームタイプを指定しますが、それがなくても1バイト(および2バイトヘッダー)を送信でき、接続を開いたままにします。数分ごとに2〜3バイトが帯域幅に大きな影響を与えることはまったくありません。
カナカ

130

WebSocketがHTTPの代わりになると想定しているようです。そうではない。これは拡張機能です。

WebSocketの主な使用例は、Webブラウザで実行され、サーバーからリアルタイムデータを受信するJavascriptアプリケーションです。ゲームが良い例です。

WebSockets以前は、Javascriptアプリケーションがサーバーと対話するための唯一の方法はを介したものXmlHttpRequestでした。ただし、これらには大きな欠点があります。クライアントが明示的に要求しない限り、サーバーはデータを送信できません。

ただし、新しいWebSocket機能により、サーバーは必要なときにいつでもデータを送信できます。これにより、AJAXロングポーリングやブラウザプラグインなどの醜いハックを使用せずに、はるかに少ないレイテンシでブラウザベースのゲームを実装できます。

ストリーミングされたリクエストとレスポンスで通常のHTTPを使用しないでください

別の回答へのコメントで、クライアントのリクエストとレスポンスの本文を非同期でストリーミングすることを提案しました。

実際、WebSocketは基本的にそれです。クライアントからWebSocket接続を開こうとする試みは、最初はHTTPリクエストのように見えますが、ヘッダーの特別なディレクティブ(アップグレード:websocket)は、サーバーにこの非同期モードで通信を開始するように指示します。WebSocketプロトコルの最初のドラフトはそれ以上ではなく、サーバーがクライアントが非同期に通信したいことを実際に理解できるようにするためのいくつかのハンドシェイクです。しかし、プロキシサーバーはHTTPの通常の要求/応答モデルに慣れているため、それによって混乱することがわかりました。潜在的な攻撃のシナリオでプロキシサーバーに対しては、発見されました。これを防ぐには、WebSocketトラフィックを通常のHTTPトラフィックとは異なるようにする必要がありました。そのため、マスキングキーが導入されました。プロトコルの最終バージョン


>>クライアントが明示的に要求しない限り、サーバーはデータを送信できません。; WebブラウザーはWebSockets接続を開始する必要があります... XMLHttpRequestと同じ
4esn0k

18
@ 4esn0kブラウザはWebSocket接続を開始します。しかし、それが確立された後、両側はいつでもデータを送信できます。XmlHttpRequestの場合はそうではありません。
フィリップ

1
なぜこれはHTTPでは不可能ですか?
4esn0k 2013

4
@Philipp、ゲームはWebSocketが輝く良い例です。ただし、最大の利益を得るのはサーバーからのリアルタイムデータではありません。HTTPストリーミング/長時間保持接続を使用すると、サーバー->クライアントのレイテンシがほぼ同じになります。また、長時間保持されるリクエストでは、クライアントがすでにリクエストを送信しており、サーバーがデータを取得するまで「リクエストを保留」しているため、サーバーはデータがある場合はいつでも効果的に送信できます。WebSocketの最大の利点は、クライアントからサーバーへの待ち時間(したがって往復)です。要求のオーバーヘッドなしでいつでも送信できるクライアントが本当の鍵です。
カナカ2013

1
@Philipp、別のメモ:JavaScriptがXMLHttpRequestとWebSocketsに加えて、サーバーとやり取りする他のメソッドがあります。これには、非表示のiframeやロングポールスクリプトタグなどがあります。詳しくは、Cometウィキペディアのページをご覧ください:en.wikipedia.org/wiki/Comet_(programming)
kanaka

27

通常のREST APIでは、HTTPを基本的な通信プロトコルとして使用します。これは、要求と応答のパラダイムに従っています。つまり、通信には、クライアントがサーバーからデータまたはリソースを要求し、サーバーがそのクライアントに応答します。ただし、HTTPはステートレスプロトコルであるため、要求と応答のサイクルごとに、ヘッダーとメタデータ情報を繰り返す必要があります。これにより、リクエストとレスポンスのサイクルが頻繁に繰り返される場合に、追加のレイテンシが発生します。

http

WebSocketを使用すると、通信は最初のHTTPハンドシェイクとして開始されますが、WebSocketsプロトコルに従うようにさらにアップグレードされます(つまり、すべてのエンティティがWebSocketsプロトコルをサポートしているわけではないため、サーバーとクライアントの両方がプロトコルに準拠している場合)。

WebSocketを使用すると、クライアントとサーバー間で全二重の永続的な接続を確立できます。これは、リクエストやレスポンスとは異なり、アプリケーションが実行されている限り(つまり、永続的である限り)接続は開いたままであり、全二重であるため、双方向の同時通信が可能です。つまり、サーバーが開始できるようになります。通信し、新しいデータ(クライアントが関心を持っている)が利用可能になったときに、クライアントに一部のデータを「プッシュ」します。

WebSocket

WebSocketsプロトコルはステートフルであり、パブリッシュ/サブスクライブ(またはPub / Sub)メッセージングパターンを実装できます。これは、リアルタイムテクノロジーで使用される主要な概念です。クライアントは繰り返し要求(ページを更新)する必要があります。このようなアプリケーションの例としては、Uber自動車の位置追跡、プッシュ通知、リアルタイムで更新される株式市場の価格、チャット、マルチプレイヤーゲーム、ライブオンラインコラボレーションツールなどがあります。

このプロトコルの歴史、それがどのようにして生まれたのか、どのように使用されているのか、自分で実装する方法について説明しているWebsocketsに関する詳細な記事をチェックしてください。

これは、私がWebSocketについて行ったプレゼンテーションのビデオであり、通常のREST APIを使用する場合との違いは次のとおりです。標準化とデータストリーミングの急激な増加の活用


24

TL; DRの場合、ここに2セントと質問の簡単なバージョンがあります。

  1. WebSocketは、HTTPに比べて次の利点を提供します。

    • 接続中の永続的なステートフル接続
    • 低レイテンシ:HTTPが必要とするように各要求の接続を再確立するオーバーヘッドがないため、サーバー/クライアント間のほぼリアルタイムの通信。
    • 全二重:サーバーとクライアントの両方が同時に送受信できます
  2. WebSocketとHTTPプロトコルはさまざまな問題を解決するように設計されています。IEWebSocketは双方向通信を改善するように設計されていますが、HTTPはステートレスで、要求/応答モデルを使用して分散されるように設計されています。レガシーの理由(ファイアウォール/プロキシの浸透)のためにポートを共有することを除いて、それらを1つのプロトコルに結合するための共通の基盤はあまりありません。


3
あなたの比較(Y)での長期ステートフルとステートレス言及することが重要
UTSAV T

15

なぜwebsocketsプロトコルの方が優れているのですか?

どっちがいいのかと並べて比較できないと思います。彼らが2つの異なる問題を解決しているからといって、それは公正な比較にはなりません。それらの要件は異なります。リンゴとオレンジを比較するようなものです。彼らは違う。

HTTPは要求/応答プロトコルです。クライアント(ブラウザ)は何かを求め、サーバーはそれを与えます。あれは。データクライアントが必要とするデータが大きい場合、サーバーはストリーミングデータを送信して、不要なバッファの問題を回避できます。ここでの主な要件または問題は、クライアントからのリクエストの方法と、クライアントがリクエストするリソース(ハイパーテキスト)に応答する方法です。それがHTTPが輝くところです。

HTTPでは、クライアント要求のみ。サーバーのみが応答します。

WebSocketは、クライアントだけが要求できる要求応答プロトコルではありません。これはソケットです(TCPソケットとよく似ています)。つまり、接続が開かれると、TCP接続の下線が閉じられるまで、どちらの側もデータを送信できます。通常のソケットと同じです。TCPソケットとの唯一の違いは、websocketがwebで使用できることです。Webでは、通常のソケットに対して多くの制限があります。ほとんどのファイアウォールは、HTTPが使用した80および433以外のポートをブロックします。プロキシと仲介者も同様に問題があります。したがって、プロトコルを既存のインフラストラクチャWebSocketに展開しやすくするには、HTTPハンドシェイクを使用してアップグレードします。つまり、初めて接続が開かれるときに、クライアントはHTTP要求を送信してサーバーに「これはHTTP要求ではありません。websocketプロトコルにアップグレードしてください」と伝えます。

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

サーバーがリクエストを理解してwebsocketプロトコルにアップグレードすると、HTTPプロトコルは適用されなくなります。

だから私の答えはどちらもどちらも優れているわけではありません。それらは完全に異なります。

なぜhttpプロトコルを更新する代わりに実装されたのですか?

まあ、HTTPという名前ですべてを作ることもできます。しかし、我々はしましょうか?2つの異なるものである場合は、2つの異なる名前を使用します。ヒクソンとマイケル・カーターもそうです。


6

他の答えはここで重要な側面に触れていないようです、そしてそれはあなたがクライアントとしてウェブブラウザをサポートすることを要求することについて言及しないことです。上記のプレーンHTTPの制限のほとんどは、ブラウザー/ JS実装で作業することを想定しています。

HTTPプロトコルは、全二重通信に完全に対応しています。クライアントにチャンクエンコーディング転送でPOSTを実行させ、サーバーにチャンクエンコーディングボディで応答を返すことは正当です。これにより、ヘッダーのオーバーヘッドが初期化時に削除されます。

したがって、探しているのが全二重であり、クライアントとサーバーの両方を制御していて、WebSocketの追加のフレーミング/機能に関心がない場合、HTTPはレイテンシ/ CPUが低いシンプルなアプローチであると主張します(レイテンシは実際には、どちらか一方のマイクロ秒以下の違いしかありません)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.