408

WebSocket と HTTP については多くのブログや議論があり、多くの開発者やサイトが WebSocket を強く支持していますが、その理由はまだ理解できません。

例(WebSocket愛好家の議論):

HTML5 Web ソケットは、Web 通信の次の進化を表しています。これは、Web 上の単一のソケットを介して動作する全二重の双方向通信チャネルです。- websocket.org

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

WebSocket との接続中に、クライアントとサーバーは、フレームごとにそれぞれ 2 バイトのデータを交換しますが、連続ポーリングを行う場合の HTTP ヘッダーは 8 キロバイトです。

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

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

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

HTTP チャンク エンコーディング - チャンク転送エンコーディング:

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 プロトコルを更新する代わりに実装したのはなぜですか?
4

6 に答える 6

619

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

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

48 バイトの HTTP ハンドシェイクは、実際の HTTP ブラウザー接続では現実的ではありません。多くのヘッダーや Cookie データを含む、要求の一部として (双方向で) 数キロバイトのデータが送信されることがよくあります。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 要求の状況が改善されますが、WebSockets および/または WebRTC DataChannel は、HTTP プロトコルよりもクライアントからサーバーへのデータ転送のレイテンシーが依然として低い可能性があります (または、WebSockets によく似たモードで使用されます)。いずれかの方法)。

更新

以下は、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 セマンティクス用に設計および最適化されています。

参考文献

HTTP :

サーバー送信イベント:

WebSocket :

SPDY :

HTTP 2.0 :

WebRTC :

クイック:

于 2013-02-05T15:54:56.433 に答える
160

WebSocket が HTTP の代わりになると想定しているようです。そうではない。延長です。

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

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

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

では、ストリーミングされたリクエストとレスポンスで通常の HTTP を使用してみませんか?

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

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

于 2013-02-05T14:54:03.997 に答える
67

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

http

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

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

ウェブソケット

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

このプロトコルの歴史、どのようにして誕生したか、何に使用され、どのように自分で実装できるかを説明している Websockets に関する詳細な記事を確認できます。

これは、WebSockets と、それらが通常の REST API の使用とどのように異なるかについて私が行ったプレゼンテーションのビデオです:標準化とデータ ストリーミングの指数関数的な上昇の活用

于 2019-04-25T15:00:59.303 に答える
38

TL;DR については、2 セントと、質問に対するより単純なバージョンを次に示します。

  1. WebSockets は、HTTP を介して次の利点を提供します。

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

于 2015-08-26T14:45:17.727 に答える
22

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つの異なる名前を好みます. ヒクソンとマイケル・カーターもそうです。

于 2018-01-19T19:25:09.787 に答える