web-dev-qa-db-ja.com

WebSocketsプロトコルとHTTP

WebSocketやHTTPに関するブログや議論はたくさんあり、多くの開発者やサイトがWebSocketを強く主張していますが、それでも理由がわかりません。

例えば(websocket愛好家の引数):

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

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

WebSocketとの接続中、クライアントとサーバーはフレームごとに2バイトのデータを交換します。これに対して、連続ポーリングを実行した場合の8キロバイトのhttpヘッダーとは異なります。

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

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

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

httpチャンクエンコーディング - http://ru.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プロトコルを更新する代わりになぜ実装されたのですか?
277
4esn0k

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

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

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. 、および QUIC など、パフォーマンスの向上と低レイテンシーを実現するために、HTTPプロトコルをリエンジニアリングする努力があります。 。これにより、通常のHTTPリクエストの状況が改善されますが、WebSocketおよび/またはWebRTC DataChannelは、クライアントからサーバーへのデータ転送のレイテンシがHTTPプロトコルよりも低い可能性があります(またはWebSocketによく似たモードで使用されます)いずれかの方法)。

更新

Webプロトコルについて考えるためのフレームワークは次のとおりです。

  • TCP:低レベル、双方向、全二重、および順序保証トランスポート層。ブラウザのサポートなし(プラグイン/ Flash経由を除く)。
  • HTTP 1.:TCPに階層化された要求/応答トランスポートプロトコル。クライアントは1つの完全な要求を行い、サーバーは1つの完全な応答を行い、その後接続が閉じられます。要求メソッド(GET、POST、HEAD)は、サーバー上のリソースに対して特定のトランザクションの意味を持ちます。
  • HTTP 1.1:HTTP 1.0の要求と応答の性質を維持しますが、複数の完全な要求/完全な応答(要求ごとに1つの応答)に対して接続を開いたままにすることができます。要求と応答にまだ完全なヘッダーがありますが、接続は再利用され、閉じられません。 HTTP 1.1では、特定のトランザクションの意味を持つ追加のリクエストメソッド(OPTIONS、PUT、DELETE、TRACE、CONNECT)も追加されました。ただし、HTTP 2.0ドラフト提案の introduction に記載されているように、HTTP 1.1パイプラインは広く展開されていないため、ブラウザーとサーバー間の遅延を解決するHTTP 1.1のユーティリティが大幅に制限されます。
  • Long-poll:HTTP(1.0または1.1のいずれか)への「ハッキング」の一種で、サーバーはクライアント要求にすぐに応答しない(またはヘッダーで部分的にのみ応答する)。サーバーが応答すると、クライアントはすぐに新しい要求を送信します(HTTP 1.1経由の場合は同じ接続を使用します)。
  • HTTPストリーミング:単一のクライアント要求に対してサーバーが複数の応答を送信できるようにするさまざまな手法(マルチパート/チャンク応答)。 W3Cはtext/event-stream MIMEタイプを使用して Server-Sent Events としてこれを標準化しています。ブラウザAPI(WebSocket APIとかなり似ています)は、EventSource APIと呼ばれます。
  • Comet/server Push:これは、ロングポールとHTTPストリーミングの両方を含む包括的な用語です。通常、Cometライブラリは複数の手法をサポートし、クロスブラウザーおよびクロスサーバーのサポートを最大化しようとします。
  • WebSockets:HTTPフレンドリーアップグレードハンドシェイクを使用するトランスポートレイヤービルトオンTCPストリーミングトランスポートであるTCPとは異なり、WebSocketsはメッセージベースのトランスポートです。メッセージはワイヤで区切られ、アプリケーションに配信される前に完全に再構築されます。 WebSocket接続は、双方向、全二重、および長期間有効です。最初のハンドシェイク要求/応答の後、トランザクションのセマンティクスはなく、メッセージごとのオーバーヘッドはほとんどありません。クライアントとサーバーはいつでもメッセージを送信でき、メッセージの受信を非同期で処理する必要があります。
  • SPDY:Googleは、より効率的なワイヤープロトコルを使用してHTTPを拡張する提案を開始しましたが、すべてのHTTPセマンティクス(要求/応答、Cookie、エンコード)を維持します。 SPDYは、新しいフレーミング形式(長さプレフィックスフレーム付き)を導入し、HTTP要求/応答ペアを新しいフレーミングレイヤーに階層化する方法を指定します。ヘッダーは圧縮でき、接続が確立された後に新しいヘッダーを送信できます。ブラウザとサーバーにSPDYの現実世界の実装があります。
  • HTTP 2.: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セマンティクス用に設計および最適化されています。

参照

447
kanaka

あなたはWebSocketがHTTPの代わりであると仮定しているようです。そうではない。それは拡張です。

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

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

しかし、新しいWebSocket機能により、サーバーは必要に応じていつでもデータを送信できます。これにより、AJAXロングポーリングやブラウザプラグインのような醜いハックを使用しなくても、はるかに短い待ち時間でブラウザベースのゲームを実装できます。

それでは、ストリーミングされたリクエストとレスポンスで通常のHTTPを使わないのです

別の回答に対するコメントでは、クライアントの要求と応答の本文を非同期にストリーミングすることを提案しました。

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

114
Philipp

TL; DRについては、ここに2セントとあなたの質問のためのより単純なバージョンがあります。

  1. WebSocketsはHTTPよりも優れたこれらの利点を提供します。

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

18
Devy

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

私たちは誰がより優れているようにそれらを並べて比較することはできないと思います。それらが解決しているという理由だけでそれは公正な比較ではない2つの異なる問題。それらの要件は異なります。リンゴとオレンジを比較するようなものです。それらは違う。

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

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

WebSocketは、クライアントだけが要求できる要求 - 応答プロトコルではありません。これはソケットです(TCP socketと非常によく似ています)。接続が開いたら、TCP接続の下線が引かれるまでどちらの側からもデータを送信できることを意味します。それは普通のソケットのようなものです。 TCPソケットとの唯一の違いは、Webで使用できるWebSocketです。 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つの異なる名前を好むでしょう。それで、Hicksonと Michael Carter

11
FranXho

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

HTTPプロトコルは全二重通信に完全に対応しています。クライアントにチャンクエンコーディング転送を使用してPOSTを実行させること、およびチャンクエンコーディング本文を使用して応答を返すことをサーバーに許可することは合法です。これにより、ヘッダーのオーバーヘッドが初期化時に取り除かれます。

それで、探しているのが全二重で、クライアントとサーバーの両方を制御し、WebSocketの余分なフレーミングや機能に興味がないのであれば、HTTPはレイテンシ/ CPUが低い単純なアプローチであると主張しますどちらもマイクロ秒以下の違いしかないでしょう)。

5
parity3

通常のREST AP​​Iは、HTTPを通信の基礎プロトコルとして使用します。これは、要求と応答のパラダイムに従います。つまり、通信ではクライアントがサーバーからデータまたはリソースを要求し、サーバーがそれに応答します。クライアント。ただし、HTTPはステートレスプロトコルであるため、すべての要求 - 応答サイクルでヘッダーとメタデータ情報を繰り返す必要があります。頻繁に繰り返される要求 - 応答サイクルの場合、これは追加の待ち時間を招く。

http

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

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

websockets

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

Websockets に関するこの記事では、このプロトコルの歴史、それがどのように生まれたのか、それが何のために使われているのか、そして自分でそれをどのように実装できるのかについて説明しています。

これが私がWebSocketについて行ったプレゼンテーションと、通常のREST AP​​Iを使用する方法との違いについてのビデオです。 標準化とデータストリーミングの急激な上昇を活用