Protocolo WebSockets vs HTTP

330

Hay muchos blogs y debates sobre websocket y HTTP, y muchos desarrolladores y sitios recomiendan firmemente los websockets, pero aún no entiendo por qué.

por ejemplo (argumentos de los amantes de websocket):

HTML5 Web Sockets representa la próxima evolución de las comunicaciones web: un canal de comunicaciones bidireccional full-duplex que opera a través de un único socket en la Web. ( http://www.websocket.org/quantum.html )

HTTP admite la transmisión: solicite la transmisión del cuerpo (lo está usando mientras carga archivos grandes) y responda la transmisión del cuerpo.

Durante la conexión con WebSocket, el cliente y el servidor intercambian datos por trama, que es de 2 bytes cada uno, en comparación con los 8 kilobytes del encabezado http cuando realiza un sondeo continuo.

¿Por qué esos 2 bytes no incluyen tcp y bajo los gastos generales de los protocolos tcp?

GET /about.html HTTP/1.1
Host: example.org

Este es un encabezado http ~ 48 bytes.

codificación fragmentada http - https://en.wikipedia.org/wiki/Chunked_transfer_encoding :

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
  • Por lo tanto, la sobrecarga por cada porción no es grande.

Además, ambos protocolos funcionan sobre TCP, por lo que todos los problemas de TCP con conexiones de larga duración siguen ahí.

Preguntas:

  1. ¿Por qué es mejor el protocolo websockets?
  2. ¿Por qué se implementó en lugar de actualizar el protocolo http?
4esn0k
fuente
2
¿Cuál es tu pregunta?
Jonas
@Jonas, 1) ¿por qué el protocolo websockets es mejor? 2) ¿Por qué se implementó en lugar de actualizar el protocolo http? 3) ¿Por qué se promocionan los websockets?
4esn0k
@JoachimPileborg, puede hacerlo con sockets TCP o http también para aplicaciones de escritorio; y debe usar WebRTC para establecer una comunicación de navegador a navegador para el sitio web
4esn0k
@JoachimPileborg, es webRTC para navegador a navegador, no websockets
4esn0k
@ 4esn0k, WS no es mejor, son diferentes y mejores para algunas tareas específicas. 3) Es una nueva característica que las personas deben conocer y abrir nuevas posibilidades para la Web
Jonas

Respuestas:

491

1) ¿Por qué es mejor el protocolo WebSockets?

WebSockets es mejor para situaciones que implican comunicación de baja latencia, especialmente para baja latencia para mensajes de cliente a servidor. Para los datos de servidor a cliente, puede obtener una latencia bastante baja utilizando conexiones de larga duración y transferencia fragmentada. Sin embargo, esto no ayuda con la latencia de cliente a servidor, lo que requiere que se establezca una nueva conexión para cada mensaje de cliente a servidor.

Su protocolo de enlace HTTP de 48 bytes no es realista para las conexiones del navegador HTTP del mundo real, donde a menudo se envían varios kilobytes de datos como parte de la solicitud (en ambas direcciones), incluidos muchos encabezados y datos de cookies. Aquí hay un ejemplo de una solicitud / respuesta para usar Chrome:

Ejemplo de solicitud (2800 bytes incluyendo datos de cookies, 490 bytes sin datos de cookies):

GET / HTTP/1.1
Host: www.cnn.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.68 Safari/537.17
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: [[[2428 byte of cookie data]]]

Respuesta de ejemplo (355 bytes):

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 13 Feb 2013 18:56:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: CG=US:TX:Arlington; path=/
Last-Modified: Wed, 13 Feb 2013 18:55:22 GMT
Vary: Accept-Encoding
Cache-Control: max-age=60, private
Expires: Wed, 13 Feb 2013 18:56:54 GMT
Content-Encoding: gzip

Tanto HTTP como WebSockets tienen enlaces de conexión inicial de tamaño equivalente, pero con una conexión de WebSocket, el enlace inicial se realiza una vez y luego los mensajes pequeños solo tienen 6 bytes de sobrecarga (2 para el encabezado y 4 para el valor de máscara). La sobrecarga de latencia no se debe tanto al tamaño de los encabezados, sino a la lógica de analizar / manejar / almacenar esos encabezados. Además, la latencia de configuración de la conexión TCP es probablemente un factor mayor que el tamaño o el tiempo de procesamiento de cada solicitud.

2) ¿Por qué se implementó en lugar de actualizar el protocolo HTTP?

Hay esfuerzos para rediseñar el protocolo HTTP para lograr un mejor rendimiento y una menor latencia, como SPDY , HTTP 2.0 y QUIC . Esto mejorará la situación para las solicitudes HTTP normales, pero es probable que WebSockets y / o WebRTC DataChannel sigan teniendo una latencia menor para la transferencia de datos de cliente a servidor que el protocolo HTTP (o se utilizará en un modo que se parece mucho a WebSockets de todos modos).

Actualización :

Aquí hay un marco para pensar en protocolos web:

  • TCP : capa de transporte de bajo nivel, bidireccional, dúplex completo y orden garantizada. No es compatible con el navegador (excepto a través de plugin / Flash).
  • HTTP 1.0 : protocolo de transporte de solicitud-respuesta en capas en TCP. El cliente realiza una solicitud completa, el servidor da una respuesta completa y luego se cierra la conexión. Los métodos de solicitud (GET, POST, HEAD) tienen un significado transaccional específico para los recursos en el servidor.
  • HTTP 1.1 : mantiene la naturaleza de solicitud-respuesta de HTTP 1.0, pero permite que la conexión permanezca abierta para múltiples solicitudes completas / respuestas completas (una respuesta por solicitud). Todavía tiene encabezados completos en la solicitud y la respuesta, pero la conexión se reutiliza y no se cierra. HTTP 1.1 también agregó algunos métodos de solicitud adicionales (OPTIONS, PUT, DELETE, TRACE, CONNECT) que también tienen significados transaccionales específicos. Sin embargo, como se señaló en la introducción al borrador de la propuesta HTTP 2.0, la canalización de HTTP 1.1 no se implementa ampliamente, por lo que esto limita en gran medida la utilidad de HTTP 1.1 para resolver la latencia entre navegadores y servidores.
  • Long-poll : una especie de "pirateo" a HTTP (ya sea 1.0 o 1.1) donde el servidor no responde de inmediato (o solo responde parcialmente con encabezados) a la solicitud del cliente. Después de una respuesta del servidor, el cliente envía de inmediato una nueva solicitud (utilizando la misma conexión si es a través de HTTP 1.1).
  • Transmisión HTTP : una variedad de técnicas (respuesta multiparte / fragmentada) que permiten al servidor enviar más de una respuesta a una sola solicitud del cliente. El W3C está estandarizando esto como eventos enviados por el servidor utilizando un text/event-streamtipo MIME. La API del navegador (que es bastante similar a la API de WebSocket) se denomina API EventSource.
  • Empuje de cometa / servidor : este es un término general que incluye la transmisión de sondeo largo y HTTP. Las bibliotecas de cometas generalmente admiten múltiples técnicas para intentar maximizar la compatibilidad entre navegadores y servidores.
  • WebSockets : un TCP de capa de transporte integrado que utiliza un protocolo de enlace de actualización compatible con HTTP. A diferencia de TCP, que es un transporte de transmisión, WebSockets es un transporte basado en mensajes: los mensajes se delimitan en el cable y se vuelven a ensamblar por completo antes de entregarlos a la aplicación. Las conexiones WebSocket son bidireccionales, full-duplex y de larga duración. Después de la solicitud / respuesta inicial de protocolo de enlace, no hay semántica transaccional y hay muy poca sobrecarga de mensajes. El cliente y el servidor pueden enviar mensajes en cualquier momento y deben manejar la recepción de mensajes de forma asincrónica.
  • SPDY : una propuesta iniciada por Google para extender HTTP utilizando un protocolo de cable más eficiente pero manteniendo toda la semántica HTTP (solicitud / respuesta, cookies, codificación). SPDY presenta un nuevo formato de trama (con marcos con longitud prefijada) y especifica una forma de superponer pares de solicitud / respuesta HTTP en la nueva capa de trama. Los encabezados se pueden comprimir y se pueden enviar nuevos encabezados después de que se haya establecido la conexión. Existen implementaciones reales de SPDY en navegadores y servidores.
  • HTTP 2.0 : tiene objetivos similares a SPDY: reduce la latencia y la sobrecarga de HTTP mientras conserva la semántica de HTTP. El borrador actual se deriva de SPDY y define un protocolo de enlace de actualización y un marco de datos que es muy similar al estándar WebSocket para el protocolo de enlace y el marco. Una propuesta de borrador HTTP 2.0 alternativa (httpbis-speed-mobility) en realidad usa WebSockets para la capa de transporte y agrega la multiplexación SPDY y el mapeo HTTP como una extensión de WebSocket (las extensiones de WebSocket se negocian durante el protocolo de enlace).
  • WebRTC / CU-WebRTC : propuestas para permitir la conectividad peer-to-peer entre navegadores. Esto puede permitir una comunicación de latencia media y máxima más baja porque el transporte subyacente es SDP / datagrama en lugar de TCP. Esto permite la entrega de paquetes / mensajes fuera de orden, lo que evita el problema de TCP de picos de latencia causados ​​por paquetes descartados que retrasan la entrega de todos los paquetes posteriores (para garantizar la entrega en orden).
  • QUIC : es un protocolo experimental destinado a reducir la latencia web sobre la de TCP. En la superficie, QUIC es muy similar a TCP + TLS + SPDY implementado en UDP. QUIC proporciona multiplexación y control de flujo equivalente a HTTP / 2, seguridad equivalente a TLS y semántica de conexión, confiabilidad y control de congestión equivalente a TCP. Debido a que TCP se implementa en los núcleos del sistema operativo y en el firmware de la caja intermedia, es casi imposible realizar cambios significativos en TCP. Sin embargo, dado que QUIC está construido sobre UDP, no tiene tales limitaciones. QUIC está diseñado y optimizado para la semántica HTTP / 2.

referencias :

canaca
fuente
1
>> Sin embargo, esto no ayuda con la latencia de cliente a servidor, lo que requiere que se establezca una nueva conexión para cada mensaje de cliente a servidor. - ¿Qué pasa con la transmisión del cuerpo de respuesta? Lo sé, la API XMLHttpRequest no permite esto, pero existe. Con la transmisión al servidor puede transmitir desde el lado del cliente.
4esn0k
8
@Philipp, hizo una pregunta que de todas formas quería investigar y documentar a fondo. Sin embargo, la cuestión de WebSockets frente a otros mecanismos basados ​​en HTTP surge con bastante frecuencia, por lo que ahora hay una buena referencia para vincular. Pero sí, parece probable que el autor de la pregunta buscara evidencia para respaldar una noción preconcebida sobre WebSockets vs HTTP, particularmente porque nunca seleccionó una respuesta ni otorgó la recompensa.
kanaka
99
Muchas gracias por esta descripción muy agradable y precisa de los protocolos.
Martin Meeser
2
@WardC caniuse.com proporciona información de compatibilidad del navegador (incluido el móvil).
kanaka
3
@ www139, no, en el nivel del protocolo WebSocket, la conexión permanece abierta hasta que un lado u otro cierre la conexión. Es posible que también deba preocuparse por los tiempos de espera de TCP (un problema con cualquier protocolo basado en TCP), pero cualquier tipo de tráfico cada minuto o dos mantendrá la conexión abierta. De hecho, la definición del protocolo WebSocket especifica un tipo de trama ping / pong, aunque incluso sin eso podría enviar un solo byte (más dos encabezados de byte) y eso mantendría la conexión abierta. 2-3 bytes cada dos minutos no es un impacto significativo en el ancho de banda en absoluto.
kanaka
130

Parece suponer que WebSocket es un reemplazo para HTTP. No lo es. Es una extensión.

El principal caso de uso de WebSockets son las aplicaciones Javascript que se ejecutan en el navegador web y reciben datos en tiempo real de un servidor. Los juegos son un buen ejemplo.

Antes de WebSockets, el único método para que las aplicaciones Javascript interactuaran con un servidor era a través XmlHttpRequest. Pero estos tienen una gran desventaja: el servidor no puede enviar datos a menos que el cliente lo haya solicitado explícitamente.

Pero la nueva característica de WebSocket permite que el servidor envíe datos cuando lo desee. Esto permite implementar juegos basados ​​en navegador con una latencia mucho más baja y sin tener que usar hacks desagradables como AJAX long-polling o plugins de navegador.

Entonces, ¿por qué no usar HTTP normal con solicitudes y respuestas transmitidas?

En un comentario a otra respuesta, sugirió simplemente transmitir la solicitud del cliente y el cuerpo de respuesta de forma asincrónica.

De hecho, WebSockets son básicamente eso. Al principio, un intento de abrir una conexión WebSocket desde el cliente parece una solicitud HTTP, pero una directiva especial en el encabezado (Actualización: websocket) le dice al servidor que comience a comunicarse en este modo asíncrono. Los primeros borradores del protocolo WebSocket no fueron mucho más que eso y un poco de apretón de manos para garantizar que el servidor realmente entienda que el cliente quiere comunicarse de forma asincrónica. Pero luego se dio cuenta de que los servidores proxy se confundirían con eso, porque están acostumbrados al modelo habitual de solicitud / respuesta de HTTP. Se descubrió un posible escenario de ataque contra servidores proxy. Para evitar esto, era necesario hacer que el tráfico de WebSocket se viera diferente a cualquier tráfico HTTP normal. Por eso se introdujeron las claves de enmascaramiento enLa versión final del protocolo .

Philipp
fuente
>> el servidor no puede enviar datos a menos que el cliente lo haya solicitado explícitamente .; El navegador web debe iniciar la conexión WebSockets ... igual que para XMLHttpRequest
4esn0k
18
@ 4esn0k El navegador inicia una conexión websocket. Pero una vez que se establece, ambas partes pueden enviar datos cuando lo deseen. Ese no es el caso de XmlHttpRequest.
Philipp
1
¿POR QUÉ esto no es posible con HTTP?
4esn0k
44
@Philipp, los juegos son un buen ejemplo donde brillan los WebSockets. Sin embargo, no se trata de datos en tiempo real del servidor donde obtiene la mayor ganancia. Puede obtener una latencia de servidor-> cliente casi tan buena usando la transmisión HTTP / conexiones de larga data. Y con solicitudes de larga data, los servidores pueden enviar de manera efectiva siempre que tengan datos porque el cliente ya ha enviado la solicitud y el servidor está "reteniendo la solicitud" hasta que tenga datos. La mayor victoria para WebSockets es con la latencia cliente-> servidor (y, por lo tanto, ida y vuelta). La clave real es que el cliente pueda enviar cuando quiera sin sobrecarga de solicitud.
kanaka
1
@Philipp, otra nota: hay otros métodos además de XMLHttpRequest y WebSockets para que JavaScript interactúe con el servidor, incluidos iframes ocultos y etiquetas de script de larga encuesta. Vea la página de Comet wikipedia para más detalles: en.wikipedia.org/wiki/Comet_(programming)
kanaka
27

Una API REST normal usa el HTTP como el protocolo subyacente para la comunicación, que sigue el paradigma de solicitud y respuesta, lo que significa que la comunicación implica que el cliente solicita algunos datos o recursos de un servidor y el servidor responde a ese cliente. Sin embargo, HTTP es un protocolo sin estado, por lo que cada ciclo de solicitud-respuesta terminará teniendo que repetir la información de encabezado y metadatos. Esto incurre en latencia adicional en caso de ciclos de solicitud-respuesta repetidos con frecuencia.

http

Con WebSockets, aunque la comunicación todavía comienza como un protocolo de enlace HTTP inicial, se trata de actualizaciones adicionales para seguir el protocolo de WebSockets (es decir, si tanto el servidor como el cliente cumplen con el protocolo, ya que no todas las entidades admiten el protocolo de WebSockets).

Ahora con WebSockets, es posible establecer una conexión dúplex completa y persistente entre el cliente y un servidor. Esto significa que, a diferencia de una solicitud y una respuesta, la conexión permanece abierta mientras la aplicación se está ejecutando (es decir, es persistente), y dado que es dúplex completo, es posible la comunicación simultánea bidireccional, es decir, ahora el servidor es capaz de iniciar una comunicación y "enviar" algunos datos al cliente cuando haya nuevos datos (que le interesen al cliente) disponibles.

websockets

El protocolo WebSockets tiene estado y le permite implementar el patrón de mensajería Publish-Subscribe (o Pub / Sub), que es el concepto principal utilizado en las tecnologías en tiempo real donde puede obtener nuevas actualizaciones en forma de envío de servidor sin el El cliente tiene que solicitar (actualizar la página) repetidamente. Ejemplos de tales aplicaciones son el seguimiento de la ubicación del automóvil Uber, las notificaciones automáticas, la actualización de los precios del mercado de valores en tiempo real, chat, juegos multijugador, herramientas de colaboración en línea en vivo, etc.

Puede consultar un artículo de inmersión profunda en Websockets que explica la historia de este protocolo, cómo surgió, para qué se utiliza y cómo puede implementarlo usted mismo.

Aquí hay un video de una presentación que hice sobre WebSockets y cómo son diferentes de usar las API REST regulares: estandarización y aprovechamiento del aumento exponencial en la transmisión de datos

Srushtika Neelakantam
fuente
24

Para el TL; DR, aquí hay 2 centavos y una versión más simple para sus preguntas:

  1. WebSockets proporciona estos beneficios sobre HTTP:

    • Conexión con estado persistente durante la duración de la conexión
    • Baja latencia: comunicación casi en tiempo real entre el servidor / cliente debido a que no existe una sobrecarga de restablecer las conexiones para cada solicitud como lo requiere HTTP.
    • Dúplex completo: tanto el servidor como el cliente pueden enviar / recibir simultáneamente
  2. WebSocket y el protocolo HTTP han sido diseñados para resolver diferentes problemas, IE WebSocket fue diseñado para mejorar la comunicación bidireccional, mientras que HTTP fue diseñado para ser sin estado, distribuido utilizando un modelo de solicitud / respuesta. Aparte de compartir los puertos por motivos heredados (penetración de firewall / proxy), no hay mucho en común para combinarlos en un solo protocolo.

Devy
fuente
3
Importante que mencionaste el término con estado y sin estado en tu comparación (S)
Utsav T
15

¿Por qué es mejor el protocolo websockets?

No creo que podamos compararlos lado a lado como quién es mejor. Esa no será una comparación justa simplemente porque están resolviendo dos problemas diferentes . Sus requisitos son diferentes. Será como comparar manzanas con naranjas. Ellos son diferentes.

HTTP es un protocolo de solicitud-respuesta. El cliente (navegador) quiere algo, el servidor se lo da. Es decir. Si el cliente de datos quiere es grande, el servidor puede enviar datos de transmisión para anular los problemas de búfer no deseados. Aquí, el requisito o problema principal es cómo realizar la solicitud de los clientes y cómo responder a los recursos (texto híbrido) que solicitan. Ahí es donde brilla HTTP.

En HTTP, solo solicitud del cliente. El servidor solo responde.

WebSocket no es un protocolo de solicitud-respuesta donde solo el cliente puede solicitar. Es un socket (muy similar al socket TCP). Es decir, una vez que la conexión está abierta, cualquier lado puede enviar datos hasta que la conexión TCP esté cerrada. Es como un enchufe normal. La única diferencia con el socket TCP es que websocket se puede usar en la web. En la web, tenemos muchas restricciones para un socket normal. La mayoría de los cortafuegos bloquearán otros puertos que no sean 80 y 433 que utilizó HTTP. Los proxies e intermediarios también serán problemáticos, por lo que para que el protocolo sea más fácil de implementar en infraestructuras existentes, Websocket utiliza el protocolo de enlace HTTP para actualizar. Eso significa que cuando se abra la primera conexión, el cliente envió una solicitud HTTP para decirle al servidor que dice "Esa no es una solicitud HTTP, actualice al protocolo websocket".

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Una vez que el servidor comprende la solicitud y se actualiza al protocolo websocket, ya no se aplica nada del protocolo HTTP.

Entonces mi respuesta es que ninguno es mejor que el otro. Son completamente diferentes

¿Por qué se implementó en lugar de actualizar el protocolo http?

Bueno, también podemos hacer todo bajo el nombre llamado HTTP . ¿Pero lo haremos? Si son dos cosas diferentes, preferiré dos nombres diferentes. También lo hacen Hickson y Michael Carter .

FranXho
fuente
6

Las otras respuestas no parecen tocar un aspecto clave aquí, y es que no mencionas la necesidad de admitir un navegador web como cliente. La mayoría de las limitaciones de HTTP simple anteriores suponen que estaría trabajando con implementaciones de navegador / JS.

El protocolo HTTP es totalmente capaz de comunicación full-duplex; Es legal que un cliente realice una POST con transferencia de codificación fragmentada y que un servidor devuelva una respuesta con un cuerpo de codificación fragmentada. Esto eliminaría la sobrecarga del encabezado solo en el momento de inicio.

Entonces, si todo lo que está buscando es full-duplex, controla tanto el cliente como el servidor, y no está interesado en el encuadre / características adicionales de websockets, entonces diría que HTTP es un enfoque más simple con menor latencia / CPU (aunque la latencia en realidad solo diferiría en microsegundos o menos para cualquiera).

paridad3
fuente