Después de terminar de leer la especificación HTTP / 2 , creo que HTTP / 2 hace obsoletos websockets para la mayoría de los casos de uso, pero tal vez no todos.
PUSH_PROMISE
(coloquialmente conocido como servidor push) no es el problema aquí. Eso es solo una optimización del rendimiento.
El principal caso de uso de Websockets en un navegador es permitir la transmisión bidireccional de datos. Entonces, creo que la pregunta del OP se convierte en si HTTP / 2 hace un mejor trabajo al habilitar la transmisión bidireccional en el navegador, y creo que sí, lo hace.
En primer lugar, es bi-di. Solo lea la introducción a la sección de transmisiones :
Un "flujo" es una secuencia bidireccional independiente de tramas intercambiadas entre el cliente y el servidor dentro de una conexión HTTP / 2. Las corrientes tienen varias características importantes:
Una única conexión HTTP / 2 puede contener múltiples flujos abiertos simultáneamente, con cualquiera de los marcos de intercalación de punto final de múltiples flujos.
Las transmisiones pueden ser establecidas y utilizadas unilateralmente o compartidas por el cliente o el servidor.
Las secuencias se pueden cerrar por cualquier punto final.
Artículos como este (vinculados en otra respuesta) están equivocados sobre este aspecto de HTTP / 2. Dicen que no es bidi. Mire, hay una cosa que no puede suceder con HTTP / 2: después de abrir la conexión, el servidor no puede iniciar una transmisión normal, solo una transmisión automática. Pero una vez que el cliente abre una transmisión enviando una solicitud, ambas partes pueden enviar tramas DATA a través de un socket persistente en cualquier momento, bidi completo.
Eso no es muy diferente de websockets: el cliente debe iniciar una solicitud de actualización de websocket antes de que el servidor también pueda enviar datos.
La mayor diferencia es que, a diferencia de los websockets, HTTP / 2 define su propia semántica de multiplexación: cómo las transmisiones obtienen identificadores y cómo los marcos transportan la identificación de la transmisión en la que se encuentran. HTTP / 2 también define la semántica de control de flujo para priorizar flujos. Esto es importante en la mayoría de las aplicaciones del mundo real de bidi.
(Ese artículo equivocado también dice que el estándar Websocket tiene multiplexación. No, no lo tiene. No es realmente difícil de averiguarlo, simplemente abra el Websocket RFC 6455 y presione ⌘-F, y escriba "multiplex". Después de leer
El protocolo está destinado a ser extensible; Las versiones futuras probablemente introducirán conceptos adicionales como la multiplexación.
Encontrará que hay una extensión de borrador de 2013 para la multiplexación de Websocket. Pero no sé qué navegadores, si los hay, son compatibles con eso. No trataría de construir mi aplicación web SPA en la parte posterior de esa extensión, especialmente con HTTP / 2, el soporte nunca llegará).
La multiplexación es exactamente el tipo de cosas que normalmente debe hacer usted mismo cada vez que abre un websocket para bidi, por ejemplo, para alimentar una aplicación de una sola página que se actualiza de forma reactiva. Me alegro de que esté en la especificación HTTP / 2, cuidada de una vez por todas.
Si desea saber qué puede hacer HTTP / 2, solo mire gRPC. gRPC se implementa a través de HTTP / 2. Mire específicamente las opciones de transmisión de dúplex medio y completo que ofrece gRPC. (Tenga en cuenta que gRPC no funciona actualmente en los navegadores, pero eso es realmente porque los navegadores (1) no exponen el marco HTTP / 2 al javascript del cliente, y (2) generalmente no admiten Trailers, que se utilizan en la especificación de gRPC)
¿Dónde podrían tener un sitio websockets? El más grande es servidor-> navegador empujó datos binarios. HTTP / 2 permite servidor-> navegador empujó datos binarios, pero no está expuesto en el navegador JS. Para aplicaciones como empujar marcos de audio y video, esta es una razón para usar websockets.
Editar: 17 de enero de 2020
Con el tiempo, esta respuesta ha ido subiendo gradualmente (lo cual es bueno, porque esta respuesta es más o menos correcta). Sin embargo, todavía hay comentarios ocasionales que dicen que no es correcto por varias razones, generalmente relacionadas con cierta confusión PUSH_PROMISE
o sobre cómo consumir realmente un servidor orientado a mensajes -> inserción de cliente en una aplicación de una sola página. Y hay un caso de uso para websockets en un navegador, que son datos binarios empujados por el servidor. Para datos de texto, incluido JSON, no use WebSockets, use SSE.
En resumen: el protocolo HTTP / 2 es bi-di completo. Sin embargo, los navegadores web modernos no exponen el protocolo HTTP / 2 orientado a marcos a JavaScript . Sin embargo, si realiza múltiples solicitudes al mismo origen a través de una conexión HTTP / 2, todo el tráfico se multiplexará en una conexión (¡y eso es lo que nos importa!).
Entonces, si necesita crear una aplicación de chat en tiempo real, digamos, donde necesita transmitir nuevos mensajes de chat a todos los clientes en la sala de chat que tienen conexiones abiertas, puede (y probablemente debería) hacerlo sin websockets.
Usaría Eventos enviados por el servidor para empujar los mensajes hacia abajo y la API Fetch para enviar las solicitudes hacia arriba. Server-Sent Events (SSE) es una API poco conocida pero bien soportada que expone una secuencia de servidor a cliente orientada a mensajes. Aunque no se parece al JavaScript del cliente, debajo del capó su navegador (si es compatible con HTTP / 2) reutilizará una única conexión TCP para multiplexar todos esos mensajes. No hay pérdida de eficiencia y, de hecho, es una ganancia sobre los websockets. ¿Necesitas múltiples transmisiones? ¡Abre múltiples EventSources! Se multiplexarán automáticamente por usted.
Además de ser más eficientes en cuanto a recursos y tener menos latencia inicial que un protocolo de enlace websocket, los eventos enviados por el servidor tienen la buena propiedad de que retroceden automáticamente y funcionan a través de HTTP / 1.1. Pero cuando tienes una conexión HTTP / 2, funcionan increíblemente bien.
Aquí hay un buen artículo con un ejemplo del mundo real de lograr el SPA de actualización reactiva.