WebSockets vs. Eventos enviados por el servidor / EventSource

839

Tanto WebSockets como los eventos enviados por el servidor son capaces de enviar datos a los navegadores. Para mí, parecen ser tecnologías competidoras. ¿Cuál es la diferencia entre ellos? ¿Cuándo elegirías uno sobre el otro?

Mads Mobæk
fuente
2
No estoy seguro de cómo los ves como competidores. Uno es síncrono y podría / podría usarse para la transferencia de datos casi en tiempo real, mientras que el otro es asíncrono y serviría para un propósito completamente diferente (enviar efectivamente mensajes similares a tostadas desde una aplicación del lado del servidor).
Brian Driscoll
54
WebSockets es bidireccional, puede enviar datos al servidor.
Andre Backlund
13
Una cosa que realmente me gusta de SSE es que es fácil de solucionar problemas ... simplemente abra una solicitud a su servidor SSE usando curl. Dado que es solo un formato de texto a través de HTTP, es fácil ver lo que está sucediendo.
Sam
77
@BrianDriscoll - asíncrono / sincrónico - ¿cuál es cuál? Por lo que puedo entender, ¿ambos permiten transferencias asincrónicas?
Dave Everitt
55
SSE no funciona en IE, websockets sí
Tyler Gillies

Respuestas:

980

Websockets y SSE (Server Sent Events) son capaces de enviar datos a los navegadores, sin embargo, no son tecnologías competidoras.

Las conexiones de Websockets pueden enviar datos al navegador y recibir datos del navegador. Un buen ejemplo de una aplicación que podría usar websockets es una aplicación de chat.

Las conexiones SSE solo pueden enviar datos al navegador. Las cotizaciones de acciones en línea o los twitters que actualizan la línea de tiempo o el feed son buenos ejemplos de una aplicación que podría beneficiarse de SSE.

En la práctica, dado que todo lo que se puede hacer con SSE también se puede hacer con Websockets, Websockets está recibiendo mucha más atención y amor, y muchos más navegadores admiten Websockets que SSE.

Sin embargo, puede ser excesivo para algunos tipos de aplicaciones, y el backend podría ser más fácil de implementar con un protocolo como SSE.

Además, SSE se puede rellenar en navegadores más antiguos que no lo admiten de forma nativa utilizando solo JavaScript. Algunas implementaciones de polyfills SSE se pueden encontrar en la página de github Modernizr .

Gotchas:

  • SSE adolece de una limitación en el número máximo de conexiones abiertas, lo que puede ser especialmente doloroso al abrir varias pestañas, ya que el límite es por navegador y se establece en un número muy bajo (6). El problema se ha marcado como "No se solucionará" en Chrome y Firefox . Este límite es por navegador + dominio, lo que significa que puede abrir 6 conexiones SSE en todas las pestañas www.example1.comy otras 6 conexiones SSE www.example2.com(gracias Phate).
  • Solo WS puede transmitir datos binarios y UTF-8, SSE está limitado a UTF-8. (Gracias a Chado Nihi).
  • Algunos firewalls empresariales con inspección de paquetes tienen problemas para manejar WebSockets (Sophos XG Firewall, WatchGuard, McAfee Web Gateway).

HTML5Rocks tiene buena información sobre SSE. De esa página:

Eventos enviados por el servidor frente a WebSockets

¿Por qué elegiría Eventos enviados por el servidor en lugar de WebSockets? Buena pregunta.

Una razón por la que los SSE se han mantenido en la sombra es porque las API posteriores, como WebSockets, proporcionan un protocolo más rico para realizar comunicaciones bidireccionales y dúplex completo. Tener un canal bidireccional es más atractivo para cosas como juegos, aplicaciones de mensajería y para casos en los que necesita actualizaciones casi en tiempo real en ambas direcciones. Sin embargo, en algunos escenarios los datos no necesitan ser enviados desde el cliente. Simplemente necesita actualizaciones de alguna acción del servidor. Algunos ejemplos serían actualizaciones de estado de amigos, cotizaciones de bolsa, fuentes de noticias u otros mecanismos automáticos de envío de datos (por ejemplo, actualizar una base de datos Web SQL del lado del cliente o un almacén de objetos IndexedDB). Si necesita enviar datos a un servidor, XMLHttpRequest siempre es un amigo.

Los SSE se envían a través de HTTP tradicional. Eso significa que no requieren un protocolo especial o implementación de servidor para funcionar. WebSockets, por otro lado, requiere conexiones full-duplex y nuevos servidores Web Socket para manejar el protocolo. Además, los eventos enviados por el servidor tienen una variedad de características de las que carece WebSockets por diseño, como la reconexión automática, los identificadores de eventos y la capacidad de enviar eventos arbitrarios.


Resumen de TLDR:

Ventajas de SSE sobre Websockets:

  • Transportado a través de HTTP simple en lugar de un protocolo personalizado
  • Se puede rellenar con javascript para "respaldar" SSE a los navegadores que aún no lo admiten.
  • Soporte integrado para reconexión e id. De evento
  • Protocolo más simple
  • No hay problemas con los firewalls corporativos que realizan la inspección de paquetes

Ventajas de Websockets sobre SSE:

  • Tiempo real, comunicación bidireccional.
  • Soporte nativo en más navegadores.

Casos de uso ideales de SSE:

  • Transmisión de ticker de stock
  • actualización de feed de twitter
  • Notificaciones al navegador

SSE gotchas:

  • Sin soporte binario
  • Límite máximo de conexiones abiertas
Alex Recarey
fuente
131
El chat es perfectamente factible con SSE: puede usar POST regular para enviar mensajes al servidor. WebSockets sería necesario solo si está implementando chat a'la Google Wave.
Kornel
135
Es cierto que el chat y otras aplicaciones en tiempo real se pueden hacer con SSE. Sin embargo, esto requiere respuestas POSTing "fuera de banda", es decir, esto no está controlado por el protocolo SSE, y no parece un buen ejemplo para una explicación básica sobre las diferencias entre SSE y Websockets. Puede implementar el chat con HTTP básico sondeando el servidor cada segundo y PUBLICANDO nuevas respuestas. Esto no significa que sea la mejor / más elegante forma de hacerlo.
Alex Recarey
14
Creo que la solución de pomeL es un gran compromiso para la mayoría de los casos, ya que JS siempre puede "enviar" cosas al servidor con un POSTE AJAX. Según mi experiencia, el problema principal ha sido, en general, la necesidad de que JS realice encuestas para obtener nueva información, pero SSE se encarga de eso. : D
Jacob Pritchett
12
@MattDiPasquale Wave envió cada clave individualmente mientras la escribía en lugar de enviar el mensaje completo de una vez. 200 bytes de sobrecarga POST para 1 pulsación de tecla serían un desperdicio en comparación con aproximadamente 6 para WebSocket.
Kornel
99
Parece un poco extraño decir que no son tecnologías competidoras y luego proceder a describir que ambas pueden usarse para lograr soluciones similares. Yo diría que eso los hace competir.
Alex
115

De acuerdo con caniuse.com:

Puede usar un polyfill solo para clientes para extender el soporte de SSE a muchos otros navegadores. Esto es menos probable con WebSockets. Algunos polyfills de EventSource:

Si necesita soportar todos los navegadores, considere usar una biblioteca como web-socket-js , SignalR o socket.io que soporta múltiples transportes como WebSockets, SSE, Forever Frame y AJAX long sondeo. A menudo, también requieren modificaciones en el lado del servidor.

Obtenga más información sobre SSE en:

Obtenga más información sobre WebSockets en:

Otras diferencias

  • WebSockets admite datos binarios arbitrarios, SSE solo usa UTF-8
Drew Noakes
fuente
3
Me gustaría señalar en 2016> 95% de los usuarios globales soportan nativamente WebSockets. Todos los navegadores y dispositivos han sido compatibles con WebSockets durante más de 4 años. Socket.IO recurrirá al sondeo largo AJAX y manejará las complejidades de emular WebSockets por usted si no es compatible, lo que hace que el soporte sea 100%. Si está utilizando cualquier cosa menos WebSockets en 2016, está utilizando tecnología desactualizada.
Nick Steele
3
@NickSteele Esa es una declaración exagerada de mierda. Confiar en estándares más antiguos está perfectamente bien si cumplen con su caso de uso y no significa que nada esté desactualizado. Es solo un estándar diferente. Ej: XHR todavía puede hacer muchas cosas que la API Fetch no puede hacer, por lo que no está desactualizado. Es diferente. He usado WS en el pasado, pero sé por experiencia que uno puede encontrar inconvenientes en forma de firewalls empresariales de ruido que bloquean las solicitudes cuando no entiende WS. SSE es súper eficiente para lo que hace, es trivialmente comprensible e implementable y fácil de depurar. Para nuestro flujo de datos unidireccional, es perfecto.
oligofren
@oligofren No hay necesidad de jurar. Si algo está diseñado para reemplazar la versión anterior, y es aceptado por la industria y mejor en todos los sentidos, por definición, el método anterior está desactualizado. Al igual que el iPhone original está desactualizado, también lo está XHR. XHR salió antes de Firefox, Chrome, el primer iPhone, antes de YouTube, Netflix, Facebook e incluso MySpace. Cuando XHR salió, Windows 98 era el mejor sistema operativo, AOL era el mejor proveedor y JSON ni siquiera existía. WebSockets reemplazó a XHR hace casi una década. Si golpea inconvenientes usando WS, lo que causó el inconveniente también está desactualizado. No hay excusa para retrasarse tanto.
Nick Steele el
44
Reemplace BS con hipérbole entonces :-) WS no es un reemplazo para XHR / HTTP más de lo que lo son los drones para los autos de entrega. Es diferentes casos de uso. WS no es HTTP y tiene diferentes puntos dulces. Terminarías reimplementando HTTP (mal) en el espacio del usuario si lo intentaras. Además, está insinuando cosas que no son hechos: WS es simplemente un protocolo bidireccional que admite el empuje del servidor. Nunca he visto ningún documento de diseño que mencione que se esté desarrollando como reemplazo de nada. ¿Fuente? La edad en sí misma no es un factor. Cuando tenga la opción, elija la implementación más simple comprobando todos sus requisitos.
oligofren
1
Hace solo dos años (2017) estaba depurando los volcados de los procesos Node JS donde el código Socket.io estaba causando una fragmentación masiva de la memoria en el proceso IIS, y terminé hablando directamente con el equipo Node de Azure. La complejidad total no es gratis. Si puede salirse con la suya con un simple script de 20 líneas como su dependencia del servidor, y al mismo tiempo poder servir a 100K clientes, lo haría. Sin embargo, me encanta WS por lo que hace, pero mira lo que necesitas antes de elegir una solución.
oligofren
16

Opera, Chrome, Safari admite SSE, Chrome, Safari admite SSE dentro de SharedWorker Firefox admite XMLHttpRequest readyState interactivo, por lo que podemos hacer que EventSource polyfil para Firefox

Yaffle
fuente
8

Websocket VS SSE


Web Sockets: es un protocolo que proporciona un canal de comunicación full-duplex a través de una única conexión TCP. Por ejemplo, una comunicación bidireccional entre el servidor y el navegador Dado que el protocolo es más complicado, el servidor y el navegador tienen que confiar en la biblioteca de websocket que essocket.io

Example - Online chat application.

SSE (Evento enviado por el servidor): en el caso de un evento enviado por el servidor, la comunicación se lleva a cabo solo del servidor al navegador y el navegador no puede enviar ningún dato al servidor. Este tipo de comunicación se utiliza principalmente cuando la necesidad es solo mostrar los datos actualizados, luego el servidor envía el mensaje cada vez que los datos se actualizan. Por ejemplo, una comunicación unidireccional entre el servidor y el navegador. Este protocolo es menos complicado, por lo que no es necesario confiar en la biblioteca externa JAVASCRIPT proporciona la EventSourceinterfaz para recibir los mensajes enviados por el servidor.

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

Una cosa a tener en cuenta:
he tenido problemas con websockets y firewalls corporativos. (Usar HTTPS ayuda pero no siempre).

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

Yo supongo que no hay tantos problemas con los eventos enviados por el servidor. Pero no lo se.

Dicho esto, los WebSockets son muy divertidos. Tengo un pequeño juego web que usa websockets (a través de Socket.IO) ( http://minibman.com )

Drew LeSueur
fuente
1
También he tenido problemas con los firewalls corporativos.
oligofren
1
Un problema que he visto con los eventos enviados por el servidor es que algunos servidores proxy / cortafuegos pueden bloquearlo porque no tiene un encabezado de longitud de contenido
Drew LeSueur
2

Aquí hay una charla sobre las diferencias entre los sockets web y los eventos enviados por el servidor. Desde Java EE 7, una API de WebSocket ya forma parte de la especificación y parece que los eventos enviados por el servidor se lanzarán en la próxima versión de la edición empresarial.

Patrick Leitermann
fuente
-3

El límite máximo de conexión no es un problema con http2 + sse.

Fue un problema en http 1

usuario1948585
fuente
Http2 permite que múltiples solicitudes en el mismo dominio sean tratadas como flujos. Esta técnica se llama multiplexación. Esto ahorra los límites de conexión del navegador por dominio, lo cual es una razón por la cual las personas hacen un fragmento de dominio con Http1.
user1948585
1
Las secuencias HTTP / 2 también tienen un número limitado, esto protege a los servidores de ser bombardeados por un solo navegador y obliga a los navegadores a limitar su multiplexación a un número limitado de secuencias, que, en nuestro caso, es lo mismo que las conexiones HTTP / 1.1. .que lo lleva de vuelta al límite de conexión SSE.
Myst
Supongo que la conexión websocket también consume recursos del servidor. samsaffron.com/archive/2015/12/29/websockets-caution-required . Siempre es bueno tener la capacidad de configurar tanto como lo permita su bolsillo.
user1948585
es probable que SSE consuma recursos similares en la mayoría de los servidores (si no más recursos debido a la pila HTTP aún presente y sus limitaciones).
Myst
1
Esta respuesta es correcta. El límite de 6 conexiones HTTP ya no existe cuando se usa HTTP / 2. Prueba: codepen.io/dunglas/pen/yLYxdxK?editors=1010 Con HTTP / 2, depende del servidor y el cliente puede negociar el número máximo de transmisiones simultáneas (100 por defecto).
Kévin Dunglas