WebSockets vs. Vom Server gesendete Ereignisse / EventSource

838

Sowohl WebSockets als auch vom Server gesendete Ereignisse können Daten an Browser senden. Für mich scheinen sie konkurrierende Technologien zu sein. Was ist der Unterschied zwischen ihnen? Wann würden Sie einen über den anderen wählen?

Mads Mobæk
quelle
2
Ich bin mir nicht sicher, wie Sie sie als konkurrierend ansehen. Einer ist synchron und könnte / würde für Daten in Echtzeit verwendet werden, während der andere asynchron ist und einem ganz anderen Zweck dienen würde (effektives Senden von toastartigen Nachrichten von einer serverseitigen App).
Brian Driscoll
54
WebSockets ist bidirektional und kann Daten an den Server senden.
Andre Backlund
13
Eine Sache, die ich an SSE wirklich mag, ist, dass es einfach ist, Fehler zu beheben. Öffnen Sie einfach eine Anfrage an Ihren SSE-Server mit curl. Da es sich nur um ein Textformat über HTTP handelt, ist es leicht zu erkennen, was los ist.
Sam
7
@BrianDriscoll - asynchron / synchron - welches ist welches? Soweit ich verstehen kann, ermöglichen beide asynchrone Übertragungen?
Dave Everitt
5
SSE funktioniert nicht auf IE, Websockets funktioniert
Tyler Gillies

Antworten:

978

Websockets und SSE (Server Sent Events) können Daten an Browser senden, sind jedoch keine konkurrierenden Technologien.

Websockets-Verbindungen können sowohl Daten an den Browser senden als auch Daten vom Browser empfangen. Ein gutes Beispiel für eine Anwendung, die Websockets verwenden könnte, ist eine Chat-Anwendung.

SSE-Verbindungen können nur Daten an den Browser senden. Online-Börsenkurse oder Twitter, die die Zeitachse oder den Feed aktualisieren, sind gute Beispiele für eine Anwendung, die von SSE profitieren könnte.

In der Praxis erhält Websockets viel mehr Aufmerksamkeit und Liebe, da alles, was mit SSE getan werden kann, auch mit Websockets erledigt werden kann, und viel mehr Browser unterstützen Websockets als SSE.

Bei einigen Anwendungstypen kann dies jedoch zu viel des Guten sein, und das Backend kann mit einem Protokoll wie SSE einfacher implementiert werden.

Darüber hinaus kann SSE in älteren Browsern, die es nicht nativ unterstützen, mit nur JavaScript polygefüllt werden. Einige Implementierungen von SSE-Polyfills finden Sie auf der Modernizr-Github-Seite .

Fallstricke:

  • SSE leidet unter einer Beschränkung auf die maximale Anzahl offener Verbindungen, was besonders beim Öffnen verschiedener Registerkarten schmerzhaft sein kann, da die Beschränkung pro Browser auf eine sehr niedrige Anzahl festgelegt ist (6). Das Problem wurde in Chrome und Firefox als "Wird nicht behoben" markiert . Dieses Limit gilt pro Browser + Domain. Das bedeutet, dass Sie 6 SSE-Verbindungen über alle Registerkarten zu www.example1.comund weitere 6 SSE-Verbindungen zu www.example2.com(danke Phate) öffnen können.
  • Nur WS kann sowohl Binärdaten als auch UTF-8 übertragen. SSE ist auf UTF-8 beschränkt. (Danke an Chado Nihi).
  • Einige Unternehmensfirewalls mit Paketinspektion haben Probleme mit WebSockets (Sophos XG Firewall, WatchGuard, McAfee Web Gateway).

HTML5Rocks enthält einige gute Informationen zu SSE. Von dieser Seite:

Vom Server gesendete Ereignisse im Vergleich zu WebSockets

Warum sollten Sie vom Server gesendete Ereignisse WebSockets vorziehen? Gute Frage.

Ein Grund, warum SSEs im Schatten gehalten wurden, ist, dass spätere APIs wie WebSockets ein umfassenderes Protokoll für die bidirektionale Vollduplex-Kommunikation bereitstellen. Ein Zwei-Wege-Kanal ist attraktiver für Dinge wie Spiele, Messaging-Apps und für Fälle, in denen Sie nahezu Echtzeit-Updates in beide Richtungen benötigen. In einigen Szenarien müssen jedoch keine Daten vom Client gesendet werden. Sie benötigen lediglich Updates von einer Serveraktion. Einige Beispiele wären Statusaktualisierungen von Freunden, Börsenticker, Newsfeeds oder andere automatisierte Daten-Push-Mechanismen (z. B. Aktualisieren einer clientseitigen Web SQL-Datenbank oder eines IndexedDB-Objektspeichers). Wenn Sie Daten an einen Server senden müssen, ist XMLHttpRequest immer ein Freund.

SSEs werden über herkömmliches HTTP gesendet. Das bedeutet, dass sie kein spezielles Protokoll oder keine spezielle Serverimplementierung benötigen, um funktionieren zu können. WebSockets hingegen erfordern Vollduplex-Verbindungen und neue Web Socket-Server, um das Protokoll verarbeiten zu können. Darüber hinaus verfügen über vom Server gesendete Ereignisse über eine Reihe von Funktionen, die WebSockets aufgrund ihres Designs fehlen, z. B. die automatische Wiederverbindung, Ereignis-IDs und die Möglichkeit, beliebige Ereignisse zu senden.


TLDR-Zusammenfassung:

Vorteile von SSE gegenüber Websockets:

  • Transport über einfaches HTTP anstelle eines benutzerdefinierten Protokolls
  • Kann mit Javascript mehrfach gefüllt werden, um SSE in Browser "zurückportieren" zu können, die dies noch nicht unterstützen.
  • Eingebaute Unterstützung für Wiederverbindung und Ereignis-ID
  • Einfacheres Protokoll
  • Keine Probleme mit Unternehmensfirewalls bei der Paketinspektion

Vorteile von Websockets gegenüber SSE:

  • Echtzeit, bidirektionale Kommunikation.
  • Native Unterstützung in mehr Browsern

Ideale Anwendungsfälle von SSE:

  • Börsenticker-Streaming
  • Aktualisierung des Twitter-Feeds
  • Benachrichtigungen an den Browser

SSE Fallstricke:

  • Keine binäre Unterstützung
  • Maximales Limit für offene Verbindungen
Alex Recarey
quelle
131
Chat ist mit SSE perfekt möglich - Sie können den regulären POST verwenden, um Nachrichten an den Server zu senden. WebSockets werden nur benötigt, wenn Sie Chat a'la Google Wave implementieren.
Kornel
135
Es ist wahr, dass Chat und andere Echtzeitanwendungen mit SSE durchgeführt werden können. Dies erfordert jedoch POST-Antworten "außerhalb des Bandes", dh dies wird nicht vom SSE-Protokoll gesteuert und scheint kein gutes Beispiel für eine grundlegende Erklärung der Unterschiede zwischen SSE und Websockets zu sein. Sie können den Chat mit einfachem HTTP implementieren, indem Sie den Server jede Sekunde abfragen und neue Antworten POSTEN. Dies bedeutet nicht, dass dies die beste / eleganteste Art ist, dies zu tun.
Alex Recarey
14
Ich denke, dass die Lösung von pomeL in den meisten Fällen ein großartiger Kompromiss ist, da JS mit einem AJAX POST immer Dinge auf den Server "pushen" kann. Nach meiner Erfahrung war das Hauptproblem im Allgemeinen die Notwendigkeit, dass JS nach neuen Informationen fragt, aber SSE kümmert sich darum. : D
Jacob Pritchett
12
@MattDiPasquale Wave hat jeden Schlüssel einzeln gesendet, während Sie ihn eingegeben haben, anstatt die vollständige Nachricht auf einmal zu senden. 200 Byte POST-Overhead für 1 Tastendruck wären verschwenderisch im Vergleich zu etwa 6 für WebSocket.
Kornel
9
Es erscheint etwas seltsam zu sagen, dass es sich nicht um konkurrierende Technologien handelt, und anschließend zu beschreiben, dass beide verwendet werden können, um ähnliche Lösungen zu erzielen. Ich würde sagen, das macht sie konkurrierend.
Alex
115

Laut caniuse.com:

Sie können eine Nur-Client-Polyfüllung verwenden, um die Unterstützung von SSE auf viele andere Browser auszudehnen. Dies ist bei WebSockets weniger wahrscheinlich. Einige EventSource-Polyfüllungen:

Wenn Sie alle Browser unterstützen müssen, sollten Sie eine Bibliothek wie web-socket-js , SignalR oder socket.io verwenden, die mehrere Transporte wie WebSockets, SSE, Forever Frame und AJAX Long Polling unterstützt. Diese erfordern häufig auch Änderungen an der Serverseite.

Erfahren Sie mehr über SSE von:

Weitere Informationen zu WebSockets finden Sie unter:

Andere Unterschiede:

  • WebSockets unterstützt beliebige Binärdaten, SSE verwendet nur UTF-8
Drew Noakes
quelle
3
Ich möchte darauf hinweisen, dass 2016> 95% der globalen Benutzer WebSockets nativ unterstützen. Alle Browser und Geräte unterstützen WebSockets seit über 4 Jahren. Socket.IO greift auf AJAX Long Polling zurück und übernimmt die Komplexität der Emulation von WebSockets für Sie, wenn dies nicht unterstützt wird, wodurch die Unterstützung zu 100% erfolgt. Wenn Sie 2016 alles andere als WebSockets verwenden, verwenden Sie veraltete Technologie.
Nick Steele
3
@ NickSteele Das ist eine Bullshit-Hype-Aussage. Sich auf ältere Standards zu verlassen ist vollkommen in Ordnung, wenn sie Ihrem Anwendungsfall entsprechen und nicht bedeuten, dass etwas veraltet ist. Es ist nur ein anderer Standard. Beispiel: XHR kann immer noch viele Dinge tun, die die Fetch-API nicht kann, daher ist es nicht veraltet. Es ist anders. Ich habe WS in der Vergangenheit verwendet, weiß aber aus Erfahrung, dass man Fehler in Form von Noise Enterprise Firewalls treffen kann, die Anforderungen blockieren, wenn es WS nicht versteht. SSE ist sehr effizient für das, was es tut, ist trivial verständlich und implementierbar und einfach zu debuggen. Für unseren Einweg-Datenfluss ist es perfekt.
Oligofren
@oligofren Keine Notwendigkeit zu schwören. Wenn etwas die vorherige Version ersetzen soll und es in jeder Hinsicht branchenüblich und in jeder Hinsicht besser ist, ist die alte Methode per Definition veraltet. So wie das ursprüngliche iPhone veraltet ist, ist auch XHR veraltet. XHR erschien vor Firefox, Chrome, dem ersten iPhone, vor YouTube, Netflix, Facebook und sogar MySpace. Als XHR herauskam, war Windows 98 das beste Betriebssystem, AOL der beste Anbieter und JSON gab es nicht einmal. WebSockets haben XHR vor fast einem Jahrzehnt ersetzt. Wenn Sie mit WS auf Haken stoßen, ist das, was den Haken verursacht hat, ebenfalls veraltet. Es gibt keine Entschuldigung, so weit zurückzubleiben.
Nick Steele
4
Ersetzen Sie BS dann durch Übertreibung :-) WS ist kein Ersatz für XHR / HTTP, genauso wenig wie Drohnen für Lieferwagen. Es sind verschiedene Anwendungsfälle. WS ist kein HTTP und hat verschiedene Sweet Spots. Wenn Sie es versuchen würden, würden Sie HTTP (schlecht) im Benutzerbereich erneut implementieren. Sie implizieren auch Dinge, die nicht mit Fakten versehen sind: WS ist einfach ein bidirektionales Protokoll, das Server-Push unterstützt. Ich habe noch nie in Designdokumenten erwähnt, dass es als Ersatz für irgendetwas entwickelt wurde. Quelle? Das Alter an sich ist kein Faktor. Wenn Sie die Wahl haben, wählen Sie die einfachste Implementierung und überprüfen Sie alle Ihre Anforderungen.
Oligofren
1
Es ist erst zwei Jahre her (2017), als ich Heap-Dumps von Node JS-Prozessen debuggte, bei denen der Socket.io-Code eine massive Speicherfragmentierung im IIS-Prozess verursachte und schließlich direkt mit dem Node-Team von Azure sprach. Die Gesamtkomplexität ist nicht kostenlos. Wenn Sie mit einem einfachen 20-Zeilen-Skript als Abhängigkeit vom Server davonkommen können und dennoch 100.000 Clients bedienen können, würde ich mich dafür entscheiden. Ich liebe WS für das, was es tut, aber schauen Sie sich an, was Sie brauchen, bevor Sie eine Lösung auswählen.
Oligofren
16

Opera, Chrome, Safari unterstützt SSE, Chrome, Safari unterstützt SSE in SharedWorker Firefox unterstützt XMLHttpRequest readyState interaktiv, sodass wir EventSource polyfil für Firefox erstellen können

Yaffle
quelle
8

Websocket VS SSE


Web Sockets - Dies ist ein Protokoll, das einen Vollduplex-Kommunikationskanal über eine einzelne TCP-Verbindung bereitstellt. Zum Beispiel eine bidirektionale Kommunikation zwischen dem Server und dem Browser Da das Protokoll komplizierter ist, müssen sich der Server und der Browser auf die Bibliothek des Websockets verlassensocket.io

Example - Online chat application.

SSE (Server-Sent Event) - Im Falle eines vom Server gesendeten Ereignisses wird die Kommunikation nur vom Server zum Browser ausgeführt und der Browser kann keine Daten an den Server senden. Diese Art der Kommunikation wird hauptsächlich verwendet, wenn nur die aktualisierten Daten angezeigt werden sollen. Der Server sendet die Nachricht dann, wenn die Daten aktualisiert werden. Zum Beispiel eine Einwegkommunikation zwischen dem Server und dem Browser. Dieses Protokoll ist weniger kompliziert, sodass Sie sich nicht auf die externe Bibliothek verlassen müssen. JAVASCRIPT selbst bietet die EventSourceSchnittstelle zum Empfangen der vom Server gesendeten Nachrichten.

Example - Online stock quotes or cricket score website.
Gaurav Tiwari
quelle
4

Eines ist zu beachten:
Ich hatte Probleme mit Websockets und Unternehmensfirewalls. (Die Verwendung von HTTPS hilft aber nicht immer.)

Siehe https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software https://github.com/sockjs/sockjs-client/issues/94

Ich gehe davon aus, dass es nicht so viele Probleme mit vom Server gesendeten Ereignissen gibt. Aber ich weiß es nicht.

Trotzdem machen WebSockets jede Menge Spaß. Ich habe ein kleines Web-Spiel, das Websockets verwendet (über Socket.IO) ( http://minibman.com )

Drew LeSueur
quelle
1
Ich hatte auch Probleme mit Unternehmensfirewalls.
Oligofren
1
Ein Problem, das ich bei vom Server gesendeten Ereignissen gesehen habe, ist, dass einige Proxys / Firewalls es möglicherweise blockieren, weil es keinen Content-Length-Header hat
Drew LeSueur
2

Hier ist ein Vortrag über die Unterschiede zwischen Web-Sockets und vom Server gesendeten Ereignissen. Seit Java EE 7 ist eine WebSocket- API bereits Teil der Spezifikation, und es scheint, dass vom Server gesendete Ereignisse in der nächsten Version der Enterprise Edition veröffentlicht werden.

Patrick Leitermann
quelle
-3

Das maximale Verbindungslimit ist bei http2 + sse kein Problem.

Es war ein Problem auf http 1

user1948585
quelle
Mit Http2 können mehrere Anforderungen in derselben Domäne als Streams behandelt werden. Diese Technik wird als Multiplexing bezeichnet. Dies spart Browser-Verbindungsbeschränkungen pro Domain, was ein Grund ist, warum Leute Domain-Sharding mit HTTP1 durchführen.
user1948585
1
Die Anzahl der HTTP / 2-Streams ist ebenfalls begrenzt. Dies schützt Server davor, von einem einzelnen Browser bombardiert zu werden, und zwingt die Browser, ihr Multiplexing auf eine begrenzte Anzahl von Streams zu beschränken - was in unserem Fall mit HTTP / 1.1-Verbindungen identisch ist. Damit kehren Sie zum SSE-Verbindungslimit zurück.
Myst
Ich gehe davon aus, dass die Websocket-Verbindung auch Serverressourcen verbraucht. samsaffron.com/archive/2015/12/29/websockets-caution-required . Es ist immer gut, so viel konfigurieren zu können, wie es Ihre Tasche erlaubt.
user1948585
Es ist wahrscheinlich, dass SSE auf den meisten Servern ähnliche Ressourcen verbraucht (wenn nicht mehr Ressourcen aufgrund des noch vorhandenen HTTP-Stacks und seiner Einschränkungen).
Myst
1
Diese Antwort ist richtig. Das Limit von 6 HTTP-Verbindungen besteht bei Verwendung von HTTP / 2 nicht mehr. Beweis: codepen.io/dunglas/pen/yLYxdxK?editors=1010 Mit HTTP / 2 ist der Server aktiv und der Client kann die maximale Anzahl gleichzeitiger Streams aushandeln (standardmäßig 100).
Kévin Dunglas