Depois de terminar de ler a especificação HTTP / 2 , acho que o HTTP / 2 faz websockets obsoletos na maioria dos casos de uso, mas talvez não todos.
PUSH_PROMISE
(conhecido coloquialmente como push do servidor) não é o problema aqui. Isso é apenas uma otimização de desempenho.
O principal caso de uso para Websockets em um navegador é ativar o fluxo bidirecional de dados. Portanto, acho que a pergunta do OP passa a ser se o HTTP / 2 faz um trabalho melhor ao ativar o fluxo bidirecional no navegador, e acho que sim.
Primeiro de tudo, é bi-di. Basta ler a introdução à seção de fluxos :
Um "fluxo" é uma sequência bidirecional independente de quadros trocados entre o cliente e o servidor em uma conexão HTTP / 2. Os fluxos têm várias características importantes:
Uma única conexão HTTP / 2 pode conter vários fluxos abertos simultaneamente, com os quadros de intercalação de terminais de vários fluxos.
Os fluxos podem ser estabelecidos e usados unilateralmente ou compartilhados pelo cliente ou servidor.
Os fluxos podem ser fechados por qualquer um dos pontos de extremidade.
Artigos como este (vinculados em outra resposta) estão errados sobre esse aspecto do HTTP / 2. Eles dizem que não é bidi. Olha, há uma coisa que não pode acontecer com o HTTP / 2: depois que a conexão é aberta, o servidor não pode iniciar um fluxo regular, apenas um fluxo push. Mas quando o cliente abre um fluxo enviando uma solicitação, os dois lados podem enviar quadros DATA através de um soquete persistente a qualquer momento - bidi completo.
Isso não é muito diferente dos websockets: o cliente precisa iniciar uma solicitação de atualização do websocket antes que o servidor também possa enviar dados.
A maior diferença é que, diferentemente dos websockets, o HTTP / 2 define sua própria semântica de multiplexação: como os fluxos obtêm identificadores e como os quadros carregam o ID do fluxo em que estão. O HTTP / 2 também define a semântica de controle de fluxo para priorizar fluxos. Isso é importante na maioria das aplicações do mundo real de bidi.
(Esse artigo errado também diz que o padrão Websocket tem multiplexação. Não, não tem. Não é realmente difícil descobrir isso, basta abrir o Websocket RFC 6455 e pressionar ⌘-F e digite "multiplex". Depois de ler
O protocolo pretende ser extensível; versões futuras provavelmente introduzirão conceitos adicionais, como multiplexação.
Você descobrirá que há uma extensão de rascunho de 2013 para a multiplexação do Websocket. Mas não sei quais navegadores, se houver, suportam isso. Eu não tentaria criar meu webapp SPA na parte de trás dessa extensão, especialmente com o HTTP / 2 chegando, o suporte pode nunca chegar).
A multiplexação é exatamente o tipo de coisa que você normalmente deve fazer sempre que abre um soquete da Web para bidi, por exemplo, para ativar um aplicativo de página única com atualização reativa. Estou feliz que esteja na especificação HTTP / 2, resolvida de uma vez por todas.
Se você quiser saber o que o HTTP / 2 pode fazer, consulte o gRPC. O gRPC é implementado no HTTP / 2. Veja especificamente as opções de streaming half e full duplex que o gRPC oferece. (Observe que o gRPC atualmente não funciona em navegadores, mas isso ocorre porque os navegadores (1) não expõem o quadro HTTP / 2 ao javascript do cliente e (2) geralmente não oferecem suporte a Trailers, que são usados em a especificação gRPC.)
Onde os websockets ainda podem ter um lugar? O grande problema é servidor-> navegador empurrado dados binários. O HTTP / 2 permite dados binários enviados pelo servidor-> pelo navegador, mas não é exposto no JS do navegador. Para aplicativos como enviar quadros de áudio e vídeo, esse é um motivo para usar websockets.
Edição: 17/01 2020
Com o tempo, essa resposta subiu gradualmente até o topo (o que é bom, porque esta resposta é mais ou menos correta). No entanto, ainda existem comentários ocasionais dizendo que isso não está correto por vários motivos, geralmente relacionados a alguma confusão PUSH_PROMISE
ou como realmente consumir servidor orientado a mensagens -> envio de cliente em um aplicativo de página única. E há um caso de uso para websockets em um navegador, que são dados binários enviados por servidor. Para dados textuais, incluindo JSON, não use websockets, use SSE.
Para recapitular: o protocolo HTTP / 2 é bi-di completo. No entanto, os navegadores modernos não expõem o protocolo HTTP / 2 orientado a quadros ao JavaScript . No entanto, se você fizer várias solicitações para a mesma origem em uma conexão HTTP / 2, todo esse tráfego ficará multiplexado em uma conexão (e é com isso que nos preocupamos!).
Portanto, se você precisa criar um aplicativo de bate-papo em tempo real, digamos, onde você precisa transmitir novas mensagens de bate-papo para todos os clientes na sala de bate-papo que possuem conexões abertas, você pode (e provavelmente deve) fazer isso sem os websockets.
Você usaria eventos enviados pelo servidor para enviar mensagens para baixo e a API de busca para enviar solicitações. Eventos enviados pelo servidor (SSE) é uma API pouco conhecida, mas bem suportada, que expõe um fluxo de servidor para cliente orientado a mensagens. Embora não pareça com o JavaScript do cliente, seu navegador (se ele suporta HTTP / 2) reutilizará uma única conexão TCP para multiplexar todas essas mensagens. Não há perda de eficiência e, de fato, é um ganho em relação aos websockets. Precisa de vários fluxos? Abra várias fontes de eventos! Eles serão automaticamente multiplexados para você.
Além de serem mais eficientes em termos de recursos e com menos latência inicial do que um handshake de websocket, os Eventos Enviados pelo Servidor têm a propriedade agradável de que eles retornam automaticamente e trabalham com HTTP / 1.1. Mas quando você tem uma conexão HTTP / 2, eles funcionam incrivelmente bem.
Aqui está um bom artigo com um exemplo do mundo real de como realizar o SPA de atualização reativa.