¿Por qué usar AJAX cuando WebSockets está disponible?

203

He estado usando WebSockets durante un tiempo, he elegido crear una herramienta de gestión de proyectos ágil para mi proyecto de último año en la Universidad utilizando el servidor Node y WebSockets. Descubrí que el uso de WebSockets proporcionaba un aumento del 624% en la cantidad de solicitudes por segundo que mi aplicación podía procesar.

Sin embargo, desde que comencé el proyecto, he leído sobre las lagunas de seguridad y algunos navegadores que eligen deshabilitar WebSockets de forma predeterminada.

Esto me lleva a la pregunta:

¿Por qué usar AJAX cuando WebSockets parece hacer un gran trabajo al reducir la latencia y la sobrecarga de recursos? ¿Hay algo que AJAX haga mejor que WebSockets?

Jack
fuente
2
Aquí hay una lista de motores que admiten sockets web. en.wikipedia.org/wiki/…
Dante

Respuestas:

209

WebSockets no pretende reemplazar AJAX y ni siquiera es estrictamente un reemplazo para Comet / long-poll (aunque hay muchos casos en los que esto tiene sentido).

El propósito de WebSockets es proporcionar una conexión de baja latencia, bidireccional, full-duplex y de larga duración entre un navegador y un servidor. WebSockets abre nuevos dominios de aplicación a las aplicaciones de navegador que realmente no eran posibles usando HTTP y AJAX (juegos interactivos, flujos de medios dinámicos, puente a protocolos de red existentes, etc.).

Sin embargo, ciertamente hay una superposición de propósitos entre WebSockets y AJAX / Comet. Por ejemplo, cuando el navegador desea recibir notificaciones de eventos del servidor (es decir, push), las técnicas Comet y WebSockets son sin duda ambas opciones viables. Si su aplicación necesita eventos push de baja latencia, este sería un factor a favor de WebSockets. Por otro lado, si necesita coexistir con los marcos existentes y las tecnologías implementadas (OAuth, API RESTful, proxies, equilibradores de carga), este sería un factor a favor de las técnicas Comet (por ahora).

Si no necesita los beneficios específicos que proporciona WebSockets, entonces probablemente sea una mejor idea seguir con las técnicas existentes como AJAX y Comet porque esto le permite reutilizar e integrarse con un enorme ecosistema existente de herramientas, tecnologías y mecanismos de seguridad. , bases de conocimiento (es decir, muchas más personas en stackoverflow conocen HTTP / Ajax / Comet que WebSockets), etc.

Por otro lado, si está creando una nueva aplicación que simplemente no funciona bien dentro de las restricciones de latencia y conexión de HTTP / Ajax / Comet, considere usar WebSockets.

Además, algunas respuestas indican que uno de los inconvenientes de WebSockets es la compatibilidad con servidores y navegadores limitados / mixtos. Permítanme difundir eso un poco. Si bien iOS (iPhone, iPad) aún admite el protocolo anterior (Hixie), la mayoría de los servidores WebSockets son compatibles con Hixie y la versión HyBi / IETF 6455 . La mayoría de las otras plataformas (si aún no tienen soporte incorporado) pueden obtener soporte de WebSockets a través de web-socket-js (Polyfill basado en Flash). Esto cubre a la gran mayoría de los usuarios de la web. Además, si está utilizando Node para el servidor back-end, considere usar Socket.IO que incluye web-socket-js como alternativa y si incluso eso no está disponible (o deshabilitado), recurrirá al uso de cualquier técnica Comet disponible para el navegador dado.

Actualización : iOS 6 ahora es compatible con el estándar actual HyBi / IETF 6455.

canaca
fuente
37
Y ahora a principios de 2014, WebSockets es prácticamente un estándar (RFC 6455) y solo Opera mini no lo admite.
Dirk Bester
44
Es cierto, Opera Mini no lo admite, pero lo más vergonzoso es la falta de soporte del navegador de Android, lo que hace que sea un poco más complejo de usar con aplicaciones basadas en webview (Cordova PhoneGap)
Miles M.
2
@kanaka, si ambos hacen archivos grandes igualmente bien, ¿por qué no simplemente enviar todo a través de websockets? ¿Por qué molestarse con páginas / datos sorprendentes cuando todo se puede enviar a través de WebSockets? (Supongamos que ya es 2020 y todos los navegadores tienen soporte para WebSockets)
Pacerier
3
@Pacerier, una respuesta completa sería larga, pero básicamente se reduce al hecho de que está intentando volver a implementar cosas que el navegador ya hace bien (almacenamiento en caché, seguridad, paralelismo, manejo de errores, etc.). Con respecto al rendimiento, aunque la velocidad de transferencia de archivos grandes sin procesar desde cero sería similar, los navegadores han tenido años para ajustar con precisión el almacenamiento en caché del contenido web (gran parte de lo cual se aplica a las solicitudes AJAX), por lo que en la práctica, es poco probable que cambiar de AJAX a WebSockets proporcione mucho beneficio para la funcionalidad existente. Pero para la comunicación bidireccional de baja latencia es una gran victoria.
kanaka
55
Lo siento, pero para mí no responde la pregunta. Básicamente solo dice que no están destinados a reemplazarse entre sí y que WS no es totalmente compatible (ahora lo es). No responde por qué preferirías AJAX sobre websocket? Tomemos Discord por ejemplo. Discord utiliza WS para enviar mensajes y eventos del servidor a los clientes, mientras que utiliza solicitudes HTTP del cliente al servidor (enviar mensajes, solicitar datos, etc.). Llegué a esta pregunta para obtener una respuesta de por qué harías eso. ¿Hay algún tipo de razón técnica por la que pondrías AJAX por encima de la conexión WS abierta?
Charlotte Dunois
63

Avance rápido hasta diciembre de 2017, Websockets es compatible con (prácticamente) todos los navegadores y su uso es muy común.

Sin embargo, esto no significa que Websockets haya logrado reemplazar AJAX, al menos no por completo, especialmente porque la adaptación HTTP / 2 está en aumento.

La respuesta breve es que AJAX sigue siendo excelente para la mayoría de las aplicaciones REST, incluso cuando se usan Websockets. Pero Dios está en los detalles, así que ...:

AJAX para encuestas?

El uso de AJAX para el sondeo (o el sondeo largo) está desapareciendo (y debería serlo), pero aún permanece en uso por dos buenas razones (principalmente para aplicaciones web más pequeñas):

  1. Para muchos desarrolladores, AJAX es más fácil de codificar, especialmente cuando se trata de codificar y diseñar el backend.

  2. Con HTTP / 2, se eliminó el costo más alto relacionado con AJAX (el establecimiento de una nueva conexión), lo que permitió que las llamadas AJAX fueran bastante efectivas, especialmente para publicar y cargar datos.

Sin embargo, Websocket push es muy superior a AJAX (no es necesario volver a autenticar o reenviar encabezados, no se necesitan viajes de ida y vuelta "sin datos", etc.). Esto fue discutido varias veces.

AJAX para DESCANSO?

Un mejor uso para AJAX son las llamadas REST API. Este uso simplifica la base del código y evita que la conexión Websocket se bloquee (especialmente en cargas de datos de tamaño mediano).

Hay una serie de razones convincentes para preferir AJAX para llamadas API REST y cargas de datos:

  1. La API AJAX fue diseñada prácticamente para llamadas API REST y es una excelente opción.

  2. Las llamadas y cargas REST usando AJAX son significativamente más fáciles de codificar, tanto en el cliente como en el backend.

  3. A medida que aumenta la carga útil de datos, las conexiones de Websocket pueden bloquearse a menos que se codifique la lógica de multiplexación / fragmentación de mensajes.

    Si se realiza una carga en una sola sendllamada de Websocket , podría bloquear una transmisión de Websocket hasta que la carga haya finalizado. Esto reducirá el rendimiento, especialmente en clientes más lentos.

Un diseño común utiliza pequeños mensajes bidireccionales transferidos a través de Websockets mientras que REST y las cargas de datos (cliente a servidor) aprovechan la facilidad de uso de AJAX para evitar que el Websocket se bloquee.

Sin embargo, en proyectos más grandes, la flexibilidad que ofrece Websockets y el equilibrio entre la complejidad del código y la gestión de recursos inclinarán la balanza a favor de Websockets.

Por ejemplo, las cargas basadas en Websocket podrían ofrecer la posibilidad de reanudar cargas grandes después de que se desconecte y restablezca una conexión (¿recuerda la película de 5GB que quería cargar?).

Al codificar la lógica de fragmentación de carga, es fácil reanudar una carga interrumpida (la parte difícil fue codificar la cosa).

¿Qué pasa con HTTP / 2 push?

Probablemente debería agregar que la función de inserción HTTP / 2 no reemplaza (y probablemente no puede) a Websockets.

Esto se discutió aquí anteriormente, pero es suficiente mencionar que una sola conexión HTTP / 2 sirve a todo el navegador (todas las pestañas / ventanas), por lo que los datos que HTTP / 2 envía no saben a qué pestaña / ventana pertenece, eliminando su capacidad para reemplazar la capacidad de Websocket de enviar datos directamente a una pestaña / ventana específica del navegador.

Si bien los Websockets son excelentes para la comunicación de datos bidireccional pequeña, AJAX aún tiene una serie de ventajas, especialmente cuando se consideran cargas útiles más grandes (cargas, etc.).

¿Y seguridad?

Bueno, en general, cuanto más confianza y control se ofrece a un programador, más poderosa es la herramienta ... y más preocupaciones de seguridad surgen.

AJAX por naturaleza tendría la ventaja, ya que su seguridad está integrada en el código del navegador (que a veces es cuestionable, pero todavía está allí).

Por otro lado, las llamadas AJAX son más susceptibles a los ataques de "hombre en el medio", mientras que los problemas de seguridad de Websockets generalmente son errores en el código de la aplicación que introdujo una falla de seguridad (por lo general, la lógica de autenticación de back-end es donde los encontrará).

Personalmente, no creo que esto sea una gran diferencia, en todo caso creo que los Websockets están un poco mejor, especialmente cuando sabes lo que estás haciendo.

Mi humilde opinión

En mi humilde opinión, usaría Websockets para todo excepto las llamadas a la API REST. Cargas de Big Data que fragmentaría y enviaría a través de Websockets cuando sea posible.

Las encuestas, en mi humilde opinión, deberían prohibirse, el costo en el tráfico de red es horrible y el empuje de Websocket es lo suficientemente fácil de administrar incluso para los nuevos desarrolladores.

Myst
fuente
2
Pequeño error gramatical 'si algo me importa ...' piensa 😀
spottedmahn
2
@spottedmahn - ¡Gracias! Supongo que es lo que sucede. Uso mi editor de código para redactar texto text
Myst
1
Disculpas, estuve ausente cuando la recompensa expiró. Mala planificación de mi parte. He establecido otra recompensa que te otorgaré después de que expiren las 23 horas.
Duncan Jones
@Myst gracias por esta gran explicación. ¿Qué preferirías para notificaciones en vivo como fb / stackoverflow? Estoy diseñando un servicio web RestFull para mi aplicación web, pero muy confundido, ¿qué debo usar para la función de notificación? AJAX o WebSockets?
TheCoder
Las notificaciones de @puspen son (en mi humilde opinión) una gran opción para Websockets. Hay muchas decisiones que tomar cuando se diseña la lógica de reconexión y las colas de notificaciones fuera de línea, pero la notificación real es fácil de codificar y se puede realizar con sockets web.
Myst
18

Además de los problemas con los navegadores más antiguos (incluido IE9, ya que WebSockets será compatible a partir de IE10), todavía hay grandes problemas con los intermediarios de red que aún no admiten WebSockets, incluidos los proxies transparentes, los proxies inversos y los equilibradores de carga. Hay algunos operadores móviles que bloquean completamente el tráfico de WebSocket (es decir, después del comando HTTP UPGRADE).

Con el paso de los años, WebSockets será cada vez más compatible, pero mientras tanto, siempre debe tener un método alternativo basado en HTTP para enviar datos a los navegadores.

Alessandro Alinone
fuente
Afortunadamente, la mayoría de los marcos de WebSocket admiten dichos fallos, incluido el uso de Flash para sockets. Socketn.IO y SignalR son ambos frameworks decentes ... aunque eres realmente limitado, como mencionas debido a los proxies y equilibradores de carga. Afortunadamente, tanto Node.JS como el próximo IIS también hacen un trabajo decente con este rol.
Rastreador1
Curioso: ¿qué operadores bloquean WebSocket en el puerto 80? ¿Qué bloque seguro de WebSocket (WSS) en el puerto 443? Esto último implica proxies web MITM forzados y transparentes ... nunca se vio en redes públicas (solo corporativas), ya que requiere instalar nuevos certificados de CA en los navegadores.
oberstet
Por ejemplo, en la actualidad, Vodafone Italia bloquea WS en el puerto 80, pero permite WSS en el puerto 443. Puede probar cualquier operador con bastante facilidad a través de nuestra página de inicio, a la que puede acceder en HTTP y HTTPS. Intenta con WebSockets y vuelve a HTTP si están bloqueados. Use esta URL para mostrar un widget en el medio que informa el transporte actual: lightstreamer.com/?s
Alessandro Alinone
17

La mayoría de las quejas que he leído sobre los sockets web y la seguridad provienen de proveedores de seguridad de herramientas de seguridad del navegador web y firewall. El problema es que no saben cómo hacer un análisis de seguridad del tráfico de websockets, porque una vez que ha realizado la actualización de HTTP al protocolo binario de websocket, el contenido del paquete y su significado es específico de la aplicación (según lo que programe). Obviamente, esta es una pesadilla logística para estas empresas cuyo sustento se basa en analizar y clasificar todo su tráfico de Internet. :)

Tim Lovell-Smith
fuente
11

Los WebSockets no funcionan en navegadores web más antiguos, y los que lo admiten a menudo tienen implementaciones diferentes. Esa es prácticamente la única buena razón por la que no se usan todo el tiempo en lugar de AJAX.

jli
fuente
8
Una mejor razón es que una solicitud AJAX es una solicitud HTTP normal, lo que significa que puede recuperar recursos HTTP; WebSockets no puede hacer eso.
Dan D.
@Dan ¿Qué sucede si, por ejemplo, los archivos de imagen se envían como base64, CSS como texto, JavaScript también como texto y luego se agregan al documento? ¿Sería plausible?
Jack
@DanD. +1, estoy de acuerdo, supongo que estaba abordando la pregunta más desde el contexto de la transmisión rápida de datos como en el ejemplo de la pregunta, pero esto es definitivamente correcto.
jli
@Dan D - a veces no quieres que toda esa basura pase por alto, como las cookies y los encabezados ...
vsync
8
@DanD., HTTP y WebSocket son dos protocolos distintos. Por supuesto, no podemos solicitar recursos HTTP usando el protocolo WebSocket por la misma razón por la que no podemos solicitar recursos WebSocket usando el protocolo HTTP. Eso no significa que el cliente no pueda solicitar archivos html y / o de imagen enviados a través del protocolo Websocket.
Pacerier
2

No creo que podamos hacer una comparación clara de Websockets y HTTP, ya que no son rivales ni resuelven los mismos problemas.

Los Websockets son una excelente opción para manejar la transmisión de datos bidireccional de larga duración casi en tiempo real, mientras que REST es ideal para comunicaciones ocasionales. El uso de websockets es una inversión considerable, por lo tanto, es una exageración para las conexiones ocasionales.

Puede encontrar que Websockets funciona mejor cuando hay grandes cargas, HTTP es un poco más rápido en algunos casos porque puede utilizar el almacenamiento en caché. Comparar REST con Websockets es como comparar manzanas con naranjas.

Deberíamos verificar cuál proporciona la mejor solución para nuestra aplicación, cuál se adapta mejor en nuestro caso de uso gana.

Gaurav Gandhi
fuente
1
La pregunta era sobre AJAX en general, no sobre REST en particular. Es cierto que AJAX se puede usar para REST, pero también se usa para sondeo y sondeo largo. Aunque estoy de acuerdo con su conclusión (como puede ver en mi respuesta), creo que su respuesta podría reflejar la distinción (tenga en cuenta que Websockets también se puede usar para REST, aunque no utilizando métodos HTTP).
Myst
@Myst Estoy de acuerdo contigo.
Gaurav Gandhi
1

Un ejemplo de las diferencias entre HTTP y Websockets en forma de una biblioteca de tamaño de cliente que puede manejar el punto final de Websocket como las API REST y los puntos finales RESTful como Websockets en el cliente. https://github.com/mikedeshazer/sockrest También, para aquellos que están tratando de consumir una API websocket en el cliente o viceversa de la forma en que están acostumbrados. Libs / sockrest.js deja bastante en claro las diferencias (o más bien se supone que debe hacerlo).

Mike D
fuente