WebSocketとサーバー送信イベント/ EventSource


838

WebSocketsServer-Sent Eventsはどちらもデータをブラウザーにプッシュできます。私には彼らは競合するテクノロジーのようです。それらの違いは何ですか?いつどちらを選ぶか?


2
競合相手としてどのように見ているかわからない。1つは同期であり、ほぼリアルタイムのデータ転送に使用できますが、もう1つは非同期であり、まったく異なる目的に役立ちます(サーバー側アプリからトーストのようなメッセージを効果的に送信します)。
Brian Driscoll、2011年

54
WebSocketは双方向で、サーバーにデータを送信できます。
Andre Backlund、2011年

13
SSEについて私が本当に気に入っていることの1つは、トラブルシューティングが簡単であるということです...を使用してSSEサーバーへのリクエストを開くだけcurlです。HTTPを介した単なるテキスト形式であるため、何が起こっているのかを簡単に確認できます。
サム

7
@BrianDriscoll-非同期/同期-どちらですか?私が理解できる限り、両方とも非同期転送を有効にしますか?
Dave Everitt 2013

5
SSEはIEでは機能せず、websocketsでは機能します
Tyler Gillies

回答:


978

WebsocketとSSE(Server Sent Events)はどちらもデータをブラウザーにプッシュできますが、競合するテクノロジーではありません。

WebSocket接続は、データをブラウザーに送信したり、ブラウザーからデータを受信したりできます。WebSocketを使用できるアプリケーションの良い例は、チャットアプリケーションです。

SSE接続はデータをブラウザーにプッシュすることのみが可能です。オンラインの株価情報、またはタイムラインやフィードを更新するTwitterは、SSEの恩恵を受けることができるアプリケーションの良い例です。

実際には、SSEで実行できることはすべてWebsocketでも実行できるため、Websocketは多くの注目と愛情を得ており、SSEよりも多くのブラウザーがWebsocketをサポートしています。

ただし、一部のタイプのアプリケーションではやり過ぎになる可能性があり、SSEなどのプロトコルを使用してバックエンドを実装する方が簡単な場合があります。

さらに、SSEは、JavaScriptだけを使用してネイティブでサポートしていない古いブラウザーにポリフィルすることができます。SSEポリフィルのいくつかの実装は、Modernizr githubページにあります

落とし穴:

  • SSEは、開いている接続の最大数に制限があるため、ブラウザごとに制限があり、非常に低い数に設定されているため、さまざまなタブを開くときに特に痛いことがあります(6)。この問題は、ChromeおよびFirefoxでは「修正されません」とマークされています。この制限はブラウザー+ドメインごとにあるため、すべてのタブで6つのSSE接続を開くことができwww.example1.com、さらに6つのSSE接続を開くことができますwww.example2.com(Phateに感謝)。
  • バイナリデータとUTF-8の両方を送信できるのはWSのみであり、SSEはUTF-8に制限されています。(Chado Nihiに感謝)。
  • パケットインスペクションを備えた一部のエンタープライズファイアウォールは、WebSocket(Sophos XG Firewall、WatchGuard、McAfee Web Gateway)の処理に問題があります。

HTML5Rocksには、SSEに関する優れた情報があります。そのページから:

サーバー送信イベントとWebSocket

なぜWebSocket経由でサーバー送信イベントを選択するのですか?良い質問。

SSEが影に隠されている理由の1つは、WebSocketのような後のAPIが双方向の全二重通信を実行するためのより豊富なプロトコルを提供するためです。双方向チャネルを持つことは、ゲーム、メッセージングアプリなどの場合や、双方向でほぼリアルタイムの更新が必要な場合に、より魅力的です。ただし、一部のシナリオでは、データをクライアントから送信する必要はありません。サーバーアクションからの更新が必要なだけです。いくつかの例は、友達のステータス更新、株価表示、ニュースフィード、またはその他の自動データプッシュメカニズム(クライアント側のWeb SQLデータベースまたはIndexedDBオブジェクトストアの更新など)です。サーバーにデータを送信する必要がある場合、XMLHttpRequestは常に友だちです。

SSEは従来のHTTP経由で送信されます。つまり、機能するために特別なプロトコルやサーバーの実装は必要ありません。一方、WebSocketは、プロトコルを処理するために、全二重接続と新しいWeb Socketサーバーを必要とします。さらに、サーバー送信イベントには、自動再接続、イベントID、任意のイベントを送信する機能など、WebSocketには設計上欠けているさまざまな機能があります。


TLDRの概要:

Webソケットに対するSSEの利点:

  • カスタムプロトコルの代わりに単純なHTTPで転送
  • JavaScriptでポリフィルして、まだサポートしていないブラウザにSSEを「バックポート」することができます。
  • 再接続とイベントIDの組み込みサポート
  • よりシンプルなプロトコル
  • パケットインスペクションを実行している企業ファイアウォールに問題はありません

SSEに対するWebsocketの利点:

  • リアルタイムの双方向通信。
  • より多くのブラウザーでのネイティブサポート

SSEの理想的な使用例:

  • 株価ティッカーストリーミング
  • Twitterフィードの更新
  • ブラウザへの通知

SSEの落とし穴:

  • バイナリサポートなし
  • 最大オープン接続制限

131
チャットはSSEで完全に実行可能です。通常のPOSTを使用してサーバーにメッセージを送信できます。WebSocketは、Google Waveでチャットを実装する場合にのみ必要です。
コーネル、

135
チャットやその他のリアルタイムアプリケーションをSSEで実行できることは事実です。ただし、これには「帯域外」でのPOST応答が必要です。つまり、これはSSEプロトコルによって制御されず、SSEとWebSocketの違いに関する基本的な説明の良い例とは思えません。サーバーを毎秒ポーリングし、新しい応答をPOSTする基本的なHTTPでチャットを実装できます。これは、それが最良/最もエレガントな方法であることを意味するものではありません。
Alex Recarey 2013年

14
JSは常にAJAX POSTを使用してサーバーに「プッシュ」できるため、pomeLのソリューションはほとんどの場合に大きな妥協案だと思います。私の経験から、主な問題は、JSが新しい情報をポーリングする必要性でしたが、SSEがそれを処理します。:D
Jacob Pritchett 2013年

12
@MattDiPasquale Waveは、一度に完全なメッセージではなく、入力したすべてのキーを個別に送信しました。1回のキーストロークで200バイトのPOSTオーバーヘッドは、WebSocketの約6バイトに比べて無駄になります。
Kornel 2013年

9
それらが競合するテクノロジーではないと言うのは少し奇妙に思われ、それらは両方とも同様のソリューションを達成するために使用できることを説明します。それは彼らを競争させていると私は言うでしょう。
アレックス、

115

caniuse.comによると:

クライアントのみのポリフィルを使用して、SSEのサポートを他の多くのブラウザーに拡張できます。これはWebSocketの場合はあまり起こりません。一部のEventSourceポリフィル:

すべてのブラウザをサポートする必要がある場合は、WebSockets、jsSignalR、またはsocket.ioなどのライブラリを使用して、WebSocket、SSE、Forever Frame、AJAXロングポーリングなどの複数のトランスポートをサポートすることを検討してください。多くの場合、サーバー側にも変更が必要です。

SSEの詳細については、以下をご覧ください。

WebSocketの詳細については、以下をご覧ください。

その他の違い:

  • WebSocketsは任意のバイナリデータをサポートし、SSEはUTF-8のみを使用します

3
2016年に指摘したいのは、グローバルユーザーの95%がWebSocketをネイティブでサポートしていることです。すべてのブラウザとデバイスは、4年間以上WebSocketをサポートしています。Socket.IOは、サポートされていない場合、AJAXロングポーリングにフォールバックし、WebSocketをエミュレートする複雑さを処理します。これにより、サポートが100%になります。2016年にWebSockets以外のものを使用している場合は、古いテクノロジーを使用しています。
Nick Steele

3
@NickSteeleそれはでたらめの誇大広告ステートメントです。古い標準に依存しても、ユースケースに適合していれば完全に問題なく、何も古くなっているわけではありません。それは単なる別の標準です。例:XHRはFetch APIで実行できない多くのことを実行できるため、古くはありません。違います。私は以前にWSを使用したことがありますが、WSを理解していないときに要求をブロックするノイズエンタープライズファイアウォールの形で障害に遭遇する可能性があることを経験から知っています。SSEは、SSEの機能に対して非常に効率的であり、簡単に理解および実装でき、デバッグが簡単です。一方向のデータフローには最適です。
オリゴフレン

@oligofren誓う必要はありません。何かが以前のバージョンを置き換えるように設計されていて、それが業界で受け入れられており、あらゆる面で優れている場合、定義上、古い方法は古くなっています。オリジナルのiPhoneが時代遅れであるように、XHRも時代遅れです。XHRは、Firefox、Chrome、最初のiPhone、YouTube、Netflix、Facebook、さらにはMySpaceの前に登場しました。XHRが登場したとき、Windows 98は最高のOSであり、AOLは最高のプロバイダーであり、JSONさえ存在しませんでした。WebSocketsはXHRをほぼ10年前に置き換えました。WSを使用して障害にぶつかった場合、障害の原因となったものも古くなっています。そこまで遅れる言い訳はありません。
Nick Steele

4
BSを双曲線に置き換えてから:-) WSは、ドローンが配送車用である以上、XHR / HTTPの代わりにはなりません。ユースケースは異なります。WSはHTTPではなく、スイートスポットが異なります。しようとすると、ユーザー空間でHTTPを(不十分に)再実装することになります。また、あなたは事実が与えられていないことを暗示しています:WSは単にサーバープッシュをサポートする双方向プロトコルです。設計ドキュメントが何かの代わりとして開発されていると述べたことはありません。ソース?年齢自体は要因ではありません。選択肢が与えられたら、すべての要件をチェックする最も単純な実装を選択します。
オリゴフレン

1
それはちょうど2年前(2017年)です。Socket.ioコードがIISプロセスで大量のメモリの断片化を引き起こし、最終的にAzureのノードチームと直接話し合ったNode JSプロセスのヒープダンプをデバッグしていました。全体の複雑さは無料ではありません。サーバーへの依存関係として単純な20行のスクリプトを使用しても、10万のクライアントにサービスを提供できる場合は、私はそれを採用します。しかし、私はWSの機能が大好きですが、ソリューションを選択する前に必要なものを確認してください。
オリゴフレン

16

Opera、Chrome、SafariはSSE、Chrome、Safariをサポートし、SharedWorker内のSSEをサポートしていますFirefoxはXMLHttpRequest readyStateインタラクティブをサポートしているため、FirefoxのEventSourceポリフィルを作成できます


8

Websocket VS SSE


Webソケット-単一のTCP接続で全二重通信チャネルを提供するプロトコルです。たとえば、サーバーとブラウザ間の双方向通信プロトコルはより複雑であるため、サーバーとブラウザは、WebSocketのライブラリに依存する必要があります。socket.io

Example - Online chat application.

SSE(サーバー送信イベント)- サーバー送信イベントの場合、通信はサーバーからブラウザーにのみ行われ、ブラウザーはサーバーにデータを送信できません。この種の通信は主に、更新されたデータを表示する必要がある場合に使用され、データが更新されるたびにサーバーがメッセージを送信します。たとえば、サーバーからブラウザへの一方向の通信です。このプロトコルはそれほど複雑ではないため、外部ライブラリJAVASCRIPT自体に依存する必要はなくEventSource、サーバーから送信されたメッセージを受信するためのインターフェースを提供します。

Example - Online stock quotes or cricket score website.

4

注意すべき点の1つ:
Webソケットと企業ファイアウォールに問題がありました。(HTTPSの使用は役立ちますが、常にではありません。)

https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software https://github.com/sockjs/sockjs-client/issues/94を参照してください

サーバー送信イベントにはそれほど問題はない思います。しかし、私にはわかりません。

とはいえ、WebSocketは非常に楽しいものです。(Socket.IO経由で)WebSocketを使用する小さなWebゲームを持っています(http://minibman.com


1
企業のファイアウォールにも問題がありました。
オリゴフレン

1
Server-Sent Eventsで見た1つの問題は、Content-Lengthヘッダーがないために一部のプロキシ/ファイアウォールがそれをブロックする可能性があることです
Drew LeSueur


-3

最大接続制限は、http2 + sseの問題ではありません。

http 1の問題でした


Http2では、同じドメイン上の複数の要求をストリームとして扱うことができます。この手法は多重化と呼ばれます。これにより、ドメインあたりの接続のブラウザー制限が節約されます。これが、人々がHttp1でドメインシャーディングを行う理由です。
user1948585

1
HTTP / 2ストリームの数も制限されています。これにより、サーバーが単一のブラウザによって攻撃されるのを防ぎ、ブラウザがその多重化を限られた数のストリームに制限します。これは、この場合、HTTP / 1.1接続と同じです。 。これにより、SSE接続制限に戻ります。
ミスト2018

websocket接続もサーバーリソースを消費すると思います。samsaffron.com/archive/2015/12/29/websockets-caution-required。あなたのポケットが許す限り多くを設定する能力があることは常に良いことです。
user1948585 2018

SSEはほとんどのサーバーで同様のリソースを消費する可能性があります(まだ存在するHTTPスタックとその制限により、それ以上ではない場合でも)。
ミスト2018

1
この答えは正しいです。HTTP / 2を使用する場合、6つのHTTP接続の制限はなくなりました。証明:codepen.io/dunglas/pen/yLYxdxK?editors=1010 HTTP / 2を使用すると、サーバーの役割を果たし、クライアントは同時ストリームの最大数(デフォルトでは100)をネゴシエートできます。
ケビンダングラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.