Ich lerne etwas über das HTTP / 2-Protokoll. Es ist ein Binärprotokoll mit kleinen Nachrichtenrahmen. Es ermöglicht Stream-Multiplexing über eine einzelne TCP-Verbindung. Konzeptionell scheint es WebSockets sehr ähnlich zu sein.
Gibt es Pläne, Websockets zu veralten und durch Header-freie HTTP / 2-Anforderungen und vom Server initiierte Push-Nachrichten zu ersetzen? Oder ergänzen WebSockets HTTP / 2?
Antworten:
Soweit ich verstanden habe, ist HTTP / 2 kein Ersatz für Websocket, sondern zielt darauf ab, das SPDY-Protokoll zu standardisieren.
In HTTP / 2 wird Server-Push hinter den Kulissen verwendet, um das Laden von Ressourcen durch den Client über den Browser zu verbessern. Als Entwickler interessiert es Sie während Ihrer Entwicklung nicht wirklich. Mit Websocket kann der Entwickler jedoch eine API verwenden, die Nachrichten mit einer eindeutigen Vollduplex-Verbindung verarbeiten und pushen kann.
Dies sind nicht die gleichen Dinge, und sie sollten sich ergänzen.
quelle
Nachdem ich gerade mit dem Lesen der HTTP / 2-Spezifikation fertig bin, denke ich, dass HTTP / 2 für die meisten Anwendungsfälle veraltete Websockets enthält, aber möglicherweise nicht für alle.
PUSH_PROMISE
(umgangssprachlich als Server-Push bezeichnet) ist hier nicht das Problem. Das ist nur eine Leistungsoptimierung.Der Hauptanwendungsfall für Websockets in einem Browser besteht darin, das bidirektionale Streaming von Daten zu ermöglichen. Ich denke also, die Frage des OP lautet, ob HTTP / 2 das bidirektionale Streaming im Browser besser ermöglicht, und ich denke, dass dies der Fall ist.
Zunächst einmal, es ist bi-di. Lesen Sie einfach die Einführung zum Abschnitt "Streams" :
Artikel wie dieser (in einer anderen Antwort verlinkt) sind in Bezug auf diesen Aspekt von HTTP / 2 falsch. Sie sagen, es ist kein Bidi. Eines kann mit HTTP / 2 nicht passieren: Nach dem Öffnen der Verbindung kann der Server keinen regulären Stream initiieren, sondern nur einen Push-Stream. Sobald der Client einen Stream durch Senden einer Anfrage öffnet, können beide Seiten jederzeit DATA-Frames über einen dauerhaften Socket senden - volles Bidi.
Das unterscheidet sich nicht wesentlich von Websockets: Der Client muss eine Websocket-Upgrade-Anforderung initiieren, bevor der Server auch Daten senden kann.
Der größte Unterschied besteht darin, dass HTTP / 2 im Gegensatz zu Websockets eine eigene Multiplex-Semantik definiert: Wie Streams Bezeichner erhalten und wie Frames die ID des Streams tragen, auf dem sie sich befinden. HTTP / 2 definiert auch die Flusssteuerungssemantik zum Priorisieren von Streams. Dies ist in den meisten realen Anwendungen von Bidi wichtig.
(Dieser falsche Artikel besagt auch, dass der Websocket-Standard Multiplexing enthält. Nein, das ist nicht der Fall. Es ist nicht wirklich schwer, das herauszufinden. Öffnen Sie einfach den Websocket RFC 6455, drücken Sie ⌘-F und geben Sie "Multiplex" ein. Nachdem Sie gelesen haben
Sie werden feststellen, dass es 2013 eine Entwurfserweiterung für Websocket-Multiplexing gibt. Aber ich weiß nicht, welche Browser das unterstützen, wenn überhaupt. Ich würde nicht versuchen, meine SPA-Webanwendung auf der Rückseite dieser Erweiterung zu erstellen, insbesondere wenn HTTP / 2 kommt, wird der Support möglicherweise nie eintreffen.
Multiplexing ist genau das, was Sie normalerweise selbst tun müssen, wenn Sie einen Websocket für Bidi öffnen, um beispielsweise eine reaktiv aktualisierte App für einzelne Seiten zu betreiben. Ich bin froh, dass es in der HTTP / 2-Spezifikation enthalten ist und ein für alle Mal erledigt wurde.
Wenn Sie wissen möchten, was HTTP / 2 kann, schauen Sie sich einfach gRPC an. gRPC ist über HTTP / 2 implementiert. Schauen Sie sich speziell die Halb- und Vollduplex-Streaming-Optionen an, die gRPC bietet. (Beachten Sie, dass gRPC derzeit nicht in Browsern funktioniert. Dies liegt jedoch daran, dass die Browser (1) den HTTP / 2-Frame nicht dem Client-Javascript aussetzen und (2) im Allgemeinen keine Trailer unterstützen, die in verwendet werden die gRPC-Spezifikation.)
Wo könnten Websockets noch einen Platz haben? Das große Problem sind Server-> Browser-Push-Binärdaten. HTTP / 2 erlaubt zwar Server-> Browser-Push-Binärdaten, ist jedoch in Browser-JS nicht verfügbar. Für Anwendungen wie das Übertragen von Audio- und Videobildern ist dies ein Grund, Websockets zu verwenden.
Bearbeiten: 17. Januar 2020
Im Laufe der Zeit ist diese Antwort allmählich nach oben gestiegen (was gut ist, weil diese Antwort mehr oder weniger richtig ist). Es gibt jedoch immer noch gelegentliche Kommentare, die besagen, dass dies aus verschiedenen Gründen nicht korrekt ist, was normalerweise auf Verwirrung darüber zurückzuführen ist,
PUSH_PROMISE
wie der nachrichtenorientierte Server -> Client-Push in einer App mit nur einer Seite tatsächlich verwendet werden soll. Und es gibt einen Anwendungsfall für Websockets in einem Browser, bei dem es sich um servergesteuerte Binärdaten handelt. Verwenden Sie für Textdaten einschließlich JSON keine Websockets, sondern SSE.Um es noch einmal zusammenzufassen: Das HTTP / 2-Protokoll ist vollständig bi-di. Jedoch nicht den Rahmen orientierte HTTP / 2 - Protokoll zu JavaScript belichten moderne Web - Browser . Wenn Sie jedoch über eine HTTP / 2-Verbindung mehrere Anfragen an denselben Ursprung stellen, wird unter der Haube der gesamte Datenverkehr auf einer Verbindung gemultiplext (und das ist uns wichtig!).
Wenn Sie also eine Echtzeit-Chat-App erstellen müssen, beispielsweise wenn Sie neue Chat-Nachrichten an alle Clients im Chatroom senden müssen, die offene Verbindungen haben, können (und sollten) Sie dies ohne Websockets tun.
Sie würden Server-Sent Events verwenden, um Nachrichten nach unten zu drücken, und die Fetch- API, um Anforderungen nach oben zu senden. Server-Sent Events (SSE) ist eine wenig bekannte, aber gut unterstützte API, die einen nachrichtenorientierten Server-zu-Client-Stream verfügbar macht. Obwohl es für das Client-JavaScript nicht so aussieht, verwendet Ihr Browser (wenn er HTTP / 2 unterstützt) unter der Haube eine einzelne TCP-Verbindung wieder, um alle diese Nachrichten zu multiplexen. Es gibt keinen Effizienzverlust und tatsächlich ist es ein Gewinn gegenüber Websockets. Benötigen Sie mehrere Streams? Öffnen Sie mehrere EventSources! Sie werden automatisch für Sie gemultiplext.
Server-Sent Events sind nicht nur ressourceneffizienter und haben eine geringere anfängliche Latenz als ein Websocket-Handshake, sondern auch die nette Eigenschaft, dass sie automatisch zurückgreifen und über HTTP / 1.1 arbeiten. Aber wenn Sie eine HTTP / 2-Verbindung haben, funktionieren sie unglaublich gut.
Hier ist ein guter Artikel mit einem realen Beispiel für die Durchführung des reaktiv aktualisierten SPA.
quelle
Ich sage Nein ( Websockets sind nicht veraltet ).
Das erste und am häufigsten ignorierte Problem ist, dass HTTP / 2-Push nicht durchsetzbar ist und möglicherweise von Proxys, Routern, anderen Vermittlern oder sogar dem Browser ignoriert wird.
dh (aus dem HTTP2-Entwurf):
Daher kann HTTP / 2 Push WebSockets nicht ersetzen.
Außerdem werden HTTP / 2-Verbindungen nach einer Weile geschlossen.
Es ist wahr, dass der Standard besagt, dass:
Aber...
Selbst wenn dieselbe Verbindung das Pushen von Inhalten ermöglicht, während diese geöffnet ist, und selbst wenn HTTP / 2 einige der Leistungsprobleme behebt, die durch HTTP / 1.1s "Keep-Alive" verursacht werden ... HTTP / 2-Verbindungen werden nicht auf unbestimmte Zeit geöffnet .
Eine Webseite kann eine HTTP / 2-Verbindung auch nach dem Schließen nicht erneut initiieren (es sei denn, wir kehren zum Long-Pulling zurück).
EDIT (2017, zwei Jahre später)
Implementierungen von HTTP / 2 zeigen, dass mehrere Browser-Registerkarten / -Fenster eine einzige HTTP / 2-Verbindung gemeinsam nutzen. Dies bedeutet, dass
push
nie bekannt ist, zu welcher Registerkarte / welchem Fenster sie gehört, sodass die Verwendungpush
als Ersatz für Websockets entfällt.EDIT (2020)
Ich bin mir nicht sicher, warum die Leute angefangen haben, die Antwort abzulehnen. Wenn überhaupt, haben die Jahre seit der ersten Veröffentlichung der Antwort bewiesen, dass HTTP / 2 WebSockets nicht ersetzen kann und nicht dafür ausgelegt ist.
Zugegeben, HTTP / 2 kann zum Tunneln von WebSocket-Verbindungen verwendet werden, für diese getunnelten Verbindungen ist jedoch weiterhin das WebSocket-Protokoll erforderlich, und sie wirken sich auf das Verhalten des HTTP / 2-Containers aus.
quelle
ssh
Terminals im Browser ist bei der Verwendung von Websockets ein Kinderspiel. Es wäre ein totaler Kopfschmerz unter HTTP / 2, besonders wenn mehr als eine Registerkarte geöffnet ist. Was ist auch, wenn der Browser (oder einer der HTTP / 2-Proxys) die Verbindung geschlossen hat? Kann der Kunde einfach davon ausgehen, dass keine neuen Daten verfügbar sind? Wir sind wieder bei der Abstimmung.onclose
Rückruf, sodass keine Abfrage erforderlich ist. Was das Multiplexing betrifft, denke ich, dass es eher eine Notwendigkeit als eine Wahl war.keep-alive
fehlgeschlagen und der einzige Weg, um den "First-in-Line" -Leistungsverlust zu vermeiden, war das Risiko des Multiplexens. Die Zeit wird es zeigen :)Die Antwort ist nein. Das Ziel zwischen den beiden ist sehr unterschiedlich. Es gibt sogar einen RFC für WebSocket über HTTP / 2, mit dem Sie mehrere WebSocket-Verbindungen über eine einzelne HTTP / 2-TCP-Pipe herstellen können.
WS über HTTP / 2 wird ein Ressourcenschonungsspiel sein, indem die Zeit zum Öffnen neuer Verbindungen verkürzt wird und mehr Kommunikationskanäle ohne die zusätzlichen Kosten für mehr Sockets, weiche IRQs und Puffer ermöglicht werden.
https://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01
quelle
Um aus diesem InfoQ- Artikel zu zitieren :
HTTP2-Push ist also wirklich etwas zwischen Ihrem Browser und dem Server, während Websockets die APIs verfügbar macht, die sowohl vom Client (Javascript, wenn es im Browser ausgeführt wird) als auch vom Anwendungscode (auf dem Server ausgeführt) zum Übertragen von Echtzeitdaten verwendet werden können.
quelle
Der Nachrichtenaustausch und das einfache Streaming (kein Audio-, Video-Streaming) können sowohl über HTTP / 2-Multiplexing als auch über WebSockets erfolgen. Es gibt also einige Überschneidungen, aber WebSockets haben ein gut etabliertes Protokoll, viele Frameworks / APIs und weniger Header-Overhead. Hier ist ein schöner Artikel zum Thema .
quelle
Es wird eine WebSocket-Implementierung in HTTP / 2 geben. https://tools.ietf.org/html/rfc8441
quelle
Derzeit macht HTTP / 2 WebSockets im April 2020 nicht überflüssig. Der größte Vorteil von WebSockets gegenüber HTTP2 ist der folgende
Bedeutet, dass HTTP / 2 keine JS-API wie WebSockets bietet, um die Kommunikation zu ermöglichen und JSON- oder andere Daten direkt von der Anwendung (z. B. Website) auf den Server zu übertragen. Soweit ich glaube, wird HTTP / 2 WebSockets nur dann überflüssig machen, wenn es API wie WebSockets für die Kommunikation mit dem Server anbietet. Bis dahin ist es nur eine aktualisierte und schnellere Version von HTTP 1.1.
quelle
Ab heute nein.
Mit HTTP / 2 können Sie im Vergleich zu HTTP eine Verbindung zu einem Server aufrechterhalten. Von dort aus können Sie mehrere Datenströme gleichzeitig haben. Die Absicht ist, dass Sie mehrere Dinge gleichzeitig pushen können, auch ohne dass der Client dies anfordert. Wenn ein Browser beispielsweise nach a fragt
index.html
, möchte der Server möglicherweise auchindex.css
und drückenindex.js
. Der Browser hat nicht danach gefragt, aber der Server stellt es möglicherweise ohne Aufforderung zur Verfügung, da davon ausgegangen werden kann, dass Sie es in wenigen Sekunden möchten.Dies ist schneller als die HTTP / 1 Alternative zu bekommen
index.html
, ist es das Parsen, braucht es zu entdeckenindex.js
undindex.css
und dann Gebäude 2 andere Anfragen für diese Dateien. Mit HTTP / 2 kann der Server Daten pushen, nach denen der Client nicht einmal gefragt hat.In diesem Zusammenhang ähnelt es WebSocket, ist aber nicht wirklich beabsichtigt. WebSocket soll eine bidirektionale Kommunikation ähnlich einer TCP-Verbindung oder einer seriellen Verbindung ermöglichen. Es ist eine Steckdose, in der beide miteinander kommunizieren. Der Hauptunterschied besteht auch darin, dass Sie beliebige Datenpakete in Rohbytes senden können, die nicht im HTTP-Protokoll gekapselt sind. Die Konzepte von Headern, Pfaden und Abfragezeichenfolgen treten nur während des Handshakes auf, WebSocket öffnet jedoch einen Datenstrom.
Der andere Unterschied besteht darin, dass Sie in Javascript einen viel genaueren Zugriff auf WebSocket erhalten, während dies bei HTTP vom Browser erledigt wird. Alles, was Sie mit HTTP erhalten, ist alles, was Sie in
XHR
/ passen könnenfetch()
. Das bedeutet , dass auch der Browser abfangen und modify HTTP - Header erhalten wird , ohne dass Sie es in der Lage zu kontrollieren (zBOrigin
,Cookies
usw.). Außerdem wird an den Browser gesendet, was HTTP / 2 pushen kann. Das bedeutet, dass JS nicht immer (wenn überhaupt) weiß, dass Dinge vorangetrieben werden. Auch hier ist es sinnvoll fürindex.css
undindex.js
weil der Browser es zwischenspeichert, aber nicht so sehr für Datenpakete.Es ist wirklich alles im Namen. HTTP steht für HyperText Transfer Protocol. Wir orientieren uns am Konzept der Übertragung von Vermögenswerten. Bei WebSocket geht es darum, eine Socket-Verbindung aufzubauen, bei der Binärdaten bidirektional weitergegeben werden.
Das, worüber wir nicht wirklich sprechen, ist SSE (Server-Sent Events). Das Übertragen von Daten an die Anwendung (JS) ist nicht die Absicht von HTTP / 2, sondern für SSE. SSE wird mit HTTP / 2 wirklich gestärkt. Es ist jedoch kein wirklicher Ersatz für WebSockets, wenn die Daten selbst wichtig sind und nicht die variablen Endpunkte. Für jeden Endpunkt in WebSocket wird ein neuer Datenstrom erstellt, der jedoch mit SSE von der bereits vorhandenen HTTP / 2-Sitzung gemeinsam genutzt wird.
Hier sind die Ziele für jedes zusammengefasst:
quelle