WebSockets vs événements envoyés par le serveur / EventSource

839

Les événements WebSockets et les événements envoyés par le serveur sont capables de transmettre des données aux navigateurs. Il me semble que ce sont des technologies concurrentes. Quelle est la différence entre eux? Quand choisiriez-vous l'un plutôt que l'autre?

Mads Mobæk
la source
2
Je ne sais pas comment vous les voyez comme concurrents. L'un est synchrone et pourrait / serait utilisé pour le transfert de données en temps quasi réel, tandis que l'autre est asynchrone et servirait un objectif entièrement différent (l'envoi efficace de messages de type toast à partir d'une application côté serveur).
Brian Driscoll
54
WebSockets est bidirectionnel, il peut envoyer des données au serveur.
Andre Backlund
13
Une chose que j'aime vraiment à propos de SSE, c'est qu'il est facile de dépanner ... ouvrez simplement une demande à votre serveur SSE en utilisant curl. Comme il ne s'agit que d'un format de texte sur HTTP, il est facile de voir ce qui se passe.
Sam
7
@BrianDriscoll - asynchrone / synchrone - qui est lequel? Pour autant que je peux comprendre les deux permettent les transferts asynchrones?
Dave Everitt
5
SSE ne fonctionne pas sur IE, websockets le fait
Tyler Gillies

Réponses:

980

Websockets et SSE (Server Sent Events) sont tous deux capables de transmettre des données aux navigateurs, mais ce ne sont pas des technologies concurrentes.

Les connexions Websockets peuvent à la fois envoyer des données au navigateur et recevoir des données du navigateur. Un bon exemple d'une application qui pourrait utiliser des websockets est une application de chat.

Les connexions SSE peuvent uniquement envoyer des données au navigateur. Les cotations boursières en ligne ou les twitters mettant à jour la chronologie ou le flux sont de bons exemples d'une application qui pourrait bénéficier de l'ESS.

Dans la pratique, car tout ce qui peut être fait avec SSE peut également être fait avec Websockets, Websockets reçoit beaucoup plus d'attention et d'amour, et beaucoup plus de navigateurs prennent en charge les Websockets que SSE.

Cependant, il peut être exagéré pour certains types d'applications et le backend pourrait être plus facile à implémenter avec un protocole tel que SSE.

De plus, SSE peut être polyfilled dans les navigateurs plus anciens qui ne le prennent pas en charge nativement en utilisant uniquement JavaScript. Certaines implémentations de polyfills SSE peuvent être trouvées sur la page github de Modernizr .

Gotchas:

  • SSE souffre d'une limitation du nombre maximal de connexions ouvertes, ce qui peut être particulièrement pénible lors de l'ouverture de divers onglets car la limite est par navigateur et définie sur un nombre très faible (6). Le problème a été marqué comme "ne sera pas résolu" dans Chrome et Firefox . Cette limite est par navigateur + domaine, ce qui signifie que vous pouvez ouvrir 6 connexions SSE dans tous les onglets vers www.example1.comet 6 autres connexions SSE vers www.example2.com(merci Phate).
  • Seul WS peut transmettre à la fois des données binaires et UTF-8, SSE est limité à UTF-8. (Merci à Chado Nihi).
  • Certains pare-feu d'entreprise avec inspection des paquets ont du mal à gérer les WebSockets (Sophos XG Firewall, WatchGuard, McAfee Web Gateway).

HTML5Rocks a de bonnes informations sur SSE. Depuis cette page:

Événements envoyés par le serveur et WebSockets

Pourquoi choisiriez-vous des événements envoyés par le serveur plutôt que des WebSockets? Bonne question.

L'une des raisons pour lesquelles les SSE ont été gardées dans l'ombre est que les API ultérieures comme WebSockets fournissent un protocole plus riche pour effectuer des communications bidirectionnelles en duplex intégral. Avoir un canal bidirectionnel est plus attrayant pour des choses comme les jeux, les applications de messagerie et pour les cas où vous avez besoin de mises à jour presque en temps réel dans les deux sens. Cependant, dans certains scénarios, les données n'ont pas besoin d'être envoyées par le client. Vous avez simplement besoin des mises à jour d'une action du serveur. Quelques exemples seraient les mises à jour de statut d'amis, les tickers de stock, les flux d'actualités ou d'autres mécanismes automatisés de transmission de données (par exemple, la mise à jour d'une base de données Web SQL côté client ou d'un magasin d'objets IndexedDB). Si vous devez envoyer des données à un serveur, XMLHttpRequest est toujours un ami.

Les SSE sont envoyées via HTTP traditionnel. Cela signifie qu'ils n'ont pas besoin d'un protocole spécial ou d'une implémentation de serveur pour fonctionner. Les WebSockets, d'autre part, nécessitent des connexions full-duplex et de nouveaux serveurs Web Socket pour gérer le protocole. En outre, les événements envoyés par le serveur ont une variété de fonctionnalités qui manquent par conception aux WebSockets, telles que la reconnexion automatique, les ID d'événement et la possibilité d'envoyer des événements arbitraires.


Résumé TLDR:

Avantages de SSE sur les Websockets:

  • Transporté via HTTP simple au lieu d'un protocole personnalisé
  • Peut être poly-rempli de javascript pour "backporter" SSE vers les navigateurs qui ne le prennent pas encore en charge.
  • Prise en charge intégrée de la reconnexion et de l'ID d'événement
  • Protocole plus simple
  • Aucun problème avec les pare-feu d'entreprise faisant l'inspection des paquets

Avantages des Websockets sur SSE:

  • Communication bidirectionnelle en temps réel.
  • Prise en charge native dans plus de navigateurs

Cas d'utilisation idéaux de l'ESS:

  • Streaming boursier boursier
  • mise à jour du fil twitter
  • Notifications au navigateur

SST gotchas:

  • Pas de support binaire
  • Limite maximale de connexions ouvertes
Alex Recarey
la source
131
Le chat est parfaitement réalisable avec SSE - vous pouvez utiliser le POST régulier pour envoyer des messages au serveur. Les WebSockets ne seraient nécessaires que si vous implémentez le chat a'la Google Wave.
Kornel
135
Il est vrai que le chat et d'autres applications en temps réel peuvent être effectués avec SSE. Cependant, cela nécessite des réponses POSTing "hors bande", c'est-à-dire que cela n'est pas contrôlé par le protocole SSE et ne semble pas être un bon exemple pour une explication de base sur les différences entre SSE et Websockets. Vous pouvez implémenter le chat avec une interrogation HTTP de base du serveur toutes les secondes et POSTing de nouvelles réponses. Cela ne signifie pas que c'est la meilleure façon / la plus élégante de le faire.
Alex Recarey
14
Je pense que la solution de pomeL est un grand compromis pour la plupart des cas, car JS peut toujours "pousser" les choses vers le serveur avec un AJAX POST. D'après mon expérience, le principal problème a généralement été la nécessité pour JS d'interroger de nouvelles informations, mais SSE s'en charge. : D
Jacob Pritchett
12
@MattDiPasquale Wave a envoyé chaque clé individuellement lorsque vous l'avez tapée au lieu d'un message complet à la fois. 200 octets de surcharge POST pour 1 frappe serait un gaspillage par rapport à environ 6 pour WebSocket.
Kornel
9
Il semble un peu étrange de dire qu'il ne s'agit pas de technologies concurrentes, puis de décrire qu'elles peuvent toutes deux être utilisées pour parvenir à des solutions similaires. Je dirais que cela les rend compétitifs.
Alex
115

Selon caniuse.com:

Vous pouvez utiliser un polyfill client uniquement pour étendre la prise en charge de SSE à de nombreux autres navigateurs. Cela est moins probable avec WebSockets. Quelques polyfills EventSource:

Si vous avez besoin de soutenir tous les navigateurs, pensez à utiliser une bibliothèque comme Web-socket-js , SignalR ou socket.io qui supportent plusieurs transports tels que WebSockets, ESS, toujours FRAME et AJAX longue interrogation. Celles-ci nécessitent souvent également des modifications côté serveur.

Apprenez-en plus sur SSE auprès de:

En savoir plus sur les WebSockets à partir de:

Autres différences:

  • WebSockets prend en charge les données binaires arbitraires, SSE utilise uniquement UTF-8
Drew Noakes
la source
3
Je voudrais souligner qu'en 2016, 95% des utilisateurs mondiaux prennent en charge nativement les WebSockets. Tous les navigateurs et appareils prennent en charge les WebSockets depuis plus de 4 ans. Socket.IO reviendra au long interrogation AJAX et gérera les complexités de l'émulation de WebSockets pour vous s'il n'est pas pris en charge, ce qui rend la prise en charge à 100%. Si vous utilisez autre chose que WebSockets en 2016, vous utilisez une technologie obsolète.
Nick Steele
3
@NickSteele C'est une déclaration de battage médiatique. S'appuyer sur des normes plus anciennes est parfaitement bien si elles répondent à votre cas d'utilisation et ne signifie pas que quelque chose est obsolète. C'est juste une norme différente. Ex: XHR peut toujours faire beaucoup de choses que l'API Fetch ne peut pas faire, donc ce n'est pas obsolète. C'est différent. J'ai utilisé WS dans le passé, mais je sais par expérience que l'on peut rencontrer des problèmes sous la forme de pare-feu d'entreprise de bruit qui bloquent les demandes lorsqu'il ne comprend pas WS. SSE est super efficace pour ce qu'il fait, est trivialement compréhensible et implémentable et facile à déboguer. Pour notre flux de données à sens unique, c'est parfait.
oligofren
@oligofren Pas besoin de jurer. Si quelque chose est conçu pour remplacer la version précédente, et qu'elle est acceptée par l'industrie et meilleure à tous égards, par définition, l'ancienne méthode est obsolète. Tout comme l'iPhone d'origine est obsolète, XHR l'est aussi. XHR est sorti avant Firefox, Chrome, le premier iPhone, avant YouTube, Netflix, Facebook et même MySpace. Lorsque XHR est sorti, Windows 98 était le meilleur système d'exploitation, AOL était le meilleur fournisseur et JSON n'existait même pas. WebSockets a remplacé XHR il y a près d'une décennie. Si vous frappez des accrocs en utilisant WS, la cause de l'accrochage est également dépassée. Il n'y a aucune excuse pour retarder jusque-là.
Nick Steele
4
Remplacez BS par hyperbole alors :-) WS n'est pas un remplacement pour XHR / HTTP pas plus que les drones pour les voitures de livraison. Ce sont des cas d'utilisation différents. WS n'est pas HTTP et a des points faibles différents. Vous finiriez par réimplémenter HTTP (mal) dans l'espace utilisateur si vous essayiez. En outre, vous impliquez des choses qui ne sont pas des faits: WS est simplement un protocole bidirectionnel prenant en charge la poussée du serveur. Je n'ai jamais vu aucun document de conception mentionner qu'il était développé en remplacement de quoi que ce soit. La source? L'âge en soi n'est pas un facteur. Lorsque vous avez le choix, choisissez l'implémentation la plus simple en vérifiant toutes vos exigences.
oligofren
1
Il y a seulement deux ans (2017), je déboguais des vidages de tas de processus Node JS où le code Socket.io provoquait une fragmentation massive de la mémoire dans le processus IIS, finissant par parler directement avec l'équipe Node d'Azure. La complexité totale n'est pas gratuite. Si vous pouvez vous en tirer avec un simple script de 20 lignes en tant que dépendance au serveur, tout en étant en mesure de servir des clients de 100 000, j'irais pour cela. J'adore WS pour ce qu'il fait, mais regardez ce dont vous avez besoin avant de choisir une solution.
oligofren
16

Opera, Chrome, Safari prend en charge SSE, Chrome, Safari prend en charge SSE à l'intérieur de SharedWorker Firefox prend en charge XMLHttpRequest readyState interactif, afin que nous puissions rendre le polyfil EventSource pour Firefox

Yaffle
la source
9

Websocket VS SSE


Web Sockets - Il s'agit d'un protocole qui fournit un canal de communication en duplex intégral sur une seule connexion TCP. Par exemple, une communication bidirectionnelle entre le serveur et le navigateur Étant donné que le protocole est plus compliqué, le serveur et le navigateur doivent s'appuyer sur la bibliothèque de websocket qui estsocket.io

Example - Online chat application.

SSE (Server-Sent Event) - En cas d'événement envoyé par le serveur, la communication est effectuée du serveur au navigateur uniquement et le navigateur ne peut envoyer aucune donnée au serveur. Ce type de communication est principalement utilisé lorsque le besoin consiste uniquement à afficher les données mises à jour, puis le serveur envoie le message chaque fois que les données sont mises à jour. Par exemple, une communication à sens unique entre le serveur et le navigateur. Ce protocole est moins compliqué, donc pas besoin de s'appuyer sur la bibliothèque externe JAVASCRIPT elle-même fournit l' EventSourceinterface pour recevoir les messages envoyés par le serveur.

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

Une chose à noter:
j'ai eu des problèmes avec les websockets et les pare-feu d'entreprise. (L'utilisation de HTTPS aide mais pas toujours.)

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

Je suppose qu'il n'y a pas autant de problèmes avec les événements envoyés par le serveur. Mais je ne sais pas.

Cela dit, les WebSockets sont très amusantes. J'ai un petit jeu web qui utilise des websockets (via Socket.IO) ( http://minibman.com )

Drew LeSueur
la source
1
J'ai également eu des problèmes avec les pare-feu d'entreprise.
oligofren
1
Un problème que j'ai vu avec les événements envoyés par le serveur est que certains proxys / pare-feu peuvent le bloquer car il n'a pas d'en-tête Content-Length
Drew LeSueur
2

Voici une présentation des différences entre les sockets Web et les événements envoyés par le serveur. Depuis Java EE 7, une API WebSocket fait déjà partie de la spécification et il semble que les événements envoyés par le serveur seront publiés dans la prochaine version de l'édition entreprise.

Patrick Leitermann
la source
-3

La limite de connexion maximale n'est pas un problème avec http2 + sse.

C'était un problème sur http 1

user1948585
la source
Http2 permet de traiter plusieurs requêtes sur le même domaine comme des flux. Cette technique est appelée multiplexage. Cela permet d'économiser les limites de connexion du navigateur par domaine, ce qui explique pourquoi les utilisateurs effectuent un partage de domaine avec Http1.
user1948585
1
Le nombre de flux HTTP / 2 est également limité, ce qui protège les serveurs contre le bombardement d'un seul navigateur et oblige les navigateurs à limiter leur multiplexage à un nombre limité de flux - ce qui, dans notre cas, est identique aux connexions HTTP / 1.1. qui vous ramène à la limite de connexion SSE.
Myst
Je suppose que la connexion Websocket consomme également des ressources de serveur. samsaffron.com/archive/2015/12/29/websockets-caution-required . C'est toujours bien d'avoir la possibilité de configurer autant que votre poche le permet.
user1948585
il est probable que SSE consommera des ressources similaires sur la plupart des serveurs (sinon plus de ressources en raison de la pile HTTP toujours présente et de ses limites).
Myst
1
Cette réponse est correcte. La limite de 6 connexions HTTP n'existe plus lors de l'utilisation de HTTP / 2. Preuve: codepen.io/dunglas/pen/yLYxdxK?editors=1010 Avec HTTP / 2, c'est le serveur et le client peut négocier le nombre maximum de flux simultanés (100 par défaut).
Kévin Dunglas