Dopo aver appena finito di leggere le specifiche HTTP / 2 , penso che HTTP / 2 abbia websocket obsoleti per la maggior parte dei casi d'uso, ma forse non tutti.
PUSH_PROMISE
(colloquialmente noto come server push) non è il problema qui. Questa è solo un'ottimizzazione delle prestazioni.
Il caso d'uso principale per Websocket in un browser è abilitare lo streaming bidirezionale di dati. Quindi, penso che la domanda dell'OP sia se HTTP / 2 faccia un lavoro migliore nell'abilitare lo streaming bidirezionale nel browser, e penso che sì, lo fa.
Prima di tutto, è bi-di. Basta leggere l'introduzione alla sezione stream :
Un "flusso" è una sequenza indipendente e bidirezionale di frame scambiati tra il client e il server all'interno di una connessione HTTP / 2. Gli stream hanno diverse caratteristiche importanti:
Una singola connessione HTTP / 2 può contenere più flussi aperti contemporaneamente, con i frame che intercalano gli endpoint da più flussi.
I flussi possono essere stabiliti e utilizzati unilateralmente o condivisi dal client o dal server.
I flussi possono essere chiusi da entrambi gli endpoint.
Articoli come questo (collegati in un'altra risposta) sono sbagliati su questo aspetto di HTTP / 2. Dicono che non è bidi. Guarda, c'è una cosa che non può accadere con HTTP / 2: dopo che la connessione è stata aperta, il server non può avviare un flusso regolare, ma solo un flusso push. Ma una volta che il client apre un flusso inviando una richiesta, entrambe le parti possono inviare frame di DATI attraverso un socket persistente in qualsiasi momento - bidi completi.
Non è molto diverso dai websocket: il client deve avviare una richiesta di aggiornamento websocket prima che anche il server possa inviare dati.
La differenza più grande è che, a differenza dei websocket, HTTP / 2 definisce la propria semantica di multiplexing: come i flussi ottengono identificatori e come i frame trasportano l'id del flusso su cui si trovano. HTTP / 2 definisce anche la semantica di controllo del flusso per l'assegnazione di priorità ai flussi. Questo è importante nella maggior parte delle applicazioni del mondo reale di bidi.
(L'articolo sbagliato dice anche che lo standard Websocket ha il multiplexing. No, non è così. Non è davvero difficile scoprirlo, basta aprire Websocket RFC 6455 e premere ⌘-F, e digitare "multiplex". Dopo aver letto
Il protocollo deve essere estensibile; le versioni future probabilmente introdurranno concetti aggiuntivi come il multiplexing.
Scoprirai che esiste una bozza di estensione 2013 per il multiplexing Websocket. Ma non so quali browser, se ce ne sono, lo supportano. Non proverei a costruire la mia webapp SPA sul retro di quell'estensione, specialmente con HTTP / 2 in arrivo, il supporto potrebbe non arrivare mai).
Il multiplexing è esattamente il tipo di cosa che normalmente devi fare da solo ogni volta che apri un websocket per bidi, ad esempio, per alimentare un'app a pagina singola che si aggiorna in modo reattivo. Sono contento che sia nelle specifiche HTTP / 2, risolto una volta per tutte.
Se vuoi sapere cosa può fare HTTP / 2, guarda gRPC. gRPC è implementato su HTTP / 2. Guarda in particolare le opzioni di streaming half e full duplex offerte da gRPC. (Si noti che gRPC attualmente non funziona nei browser, ma in realtà è perché i browser (1) non espongono il frame HTTP / 2 al javascript del client e (2) generalmente non supportano i trailer, che vengono utilizzati in le specifiche gRPC.)
Dove potrebbero ancora avere un posto i websocket? Il più grande è il server-> i dati binari inviati dal browser. HTTP / 2 consente dati binari inviati dal server e dal browser, ma non è esposto nel browser JS. Per applicazioni come il push di frame audio e video, questo è un motivo per utilizzare i websocket.
Modifica: 17 gennaio 2020
Nel corso del tempo questa risposta è gradualmente salita in cima (il che è positivo, perché questa risposta è più o meno corretta). Tuttavia ci sono ancora commenti occasionali che dicono che non è corretto per vari motivi, di solito legati a qualche confusione su PUSH_PROMISE
o come effettivamente consumare server orientato ai messaggi -> push client in un'app a pagina singola. E c'è un caso d'uso per i websocket in un browser, che sono dati binari inviati dal server. Per i dati testuali incluso JSON, non utilizzare websocket, usa SSE.
Ricapitolando: il protocollo HTTP / 2 è completo bi-di. Tuttavia, i browser Web moderni non espongono il protocollo HTTP / 2 orientato ai frame a JavaScript . Tuttavia, se effettui più richieste alla stessa origine su una connessione HTTP / 2, sotto il cofano tutto quel traffico viene multiplexato su una connessione (ed è quello che ci interessa!).
Quindi, se hai bisogno di creare un'app di chat in tempo reale, diciamo, dove devi trasmettere nuovi messaggi di chat a tutti i client nella chat room che hanno connessioni aperte, puoi (e probabilmente dovresti) farlo senza websocket.
Dovresti utilizzare gli eventi inviati dal server per inviare i messaggi verso il basso e l' API Fetch per inviare le richieste. Server-Sent Events (SSE) è un'API poco conosciuta ma ben supportata che espone un flusso da server a client orientato ai messaggi. Sebbene non sembri al client JavaScript, sotto il cofano il tuo browser (se supporta HTTP / 2) riutilizzerà una singola connessione TCP per multiplexare tutti quei messaggi. Non c'è perdita di efficienza e in effetti è un guadagno rispetto ai websocket. Hai bisogno di più stream? Apri più EventSource! Verranno automaticamente multiplexati per te.
Oltre ad essere più efficienti in termini di risorse e ad avere una latenza iniziale inferiore rispetto a un handshake websocket, gli eventi inviati dal server hanno la bella proprietà che si ritirano automaticamente e funzionano su HTTP / 1.1. Ma quando hai una connessione HTTP / 2 funzionano incredibilmente bene.
Ecco un buon articolo con un esempio reale di come realizzare la SPA con aggiornamento reattivo.