Czy HTTP / 2 powoduje, że websockets stają się przestarzałe?

268

Uczę się o protokole HTTP / 2. Jest to protokół binarny z małymi ramkami wiadomości. Umożliwia multipleksowanie strumieniowe przez pojedyncze połączenie TCP. Pod względem koncepcyjnym wydaje się bardzo podobny do WebSockets.

Czy są plany przestarzałych gniazd sieciowych i zastąpienia ich jakimś rodzajem żądań HTTP / 2 bez nagłówków i wiadomości push inicjowanych przez serwer? A może WebSockets uzupełnią HTTP / 2?

Vbezhenar
źródło
Myślę, że zaakceptowana odpowiedź jest poprawna, nadal preferowane jest rozwiązanie websockets dla aplikacji internetowych do dwukierunkowej komunikacji z serwerem, w tym komunikatów przekazywanych przez serwer. HTTP jest używany w więcej niż tylko przeglądarkach, a gdy zarówno klient, jak i serwer mogą korzystać z niskopoziomowego interfejsu API, nie potrzebują gniazd sieciowych. Nadal większość ludzi używa HTTP do aplikacji internetowych i martwi się przede wszystkim interfejsami API z obsługą JavaScript. Jeśli moderatorzy uważają, że zaakceptowana odpowiedź powinna być inna, nie jestem temu przeciwny, ponieważ to pytanie najwyraźniej generuje wiele poglądów, a moja opinia może być błędna.
vbezhenar

Odpowiedzi:

161

Z tego co zrozumiałem HTTP / 2 nie zastępuje websocket, ale ma na celu standaryzację protokołu SPDY.

W HTTP / 2 funkcja push-server jest używana za sceną, aby usprawnić ładowanie zasobów przez klienta z przeglądarki. Jako programista tak naprawdę nie dbasz o to podczas tworzenia. Jednak w przypadku Websocket deweloper może korzystać z interfejsu API, który może odbierać i przekazywać wiadomości za pomocą unikalnego połączenia pełnego dupleksu.

To nie są te same rzeczy i powinny się wzajemnie uzupełniać.

Guillaume D.
źródło
3
Dziękuję Guillaume za odpowiedź. Zastanawiam się jednak, czy ty (lub ktoś) mógłbyś dodać jakieś odniesienie ze specyfikacji HTTP / 2. Co przeczytałem z blogów i tak dalej - w HTTP / 2 jest prawdziwa komunikacja dwukierunkowa?
Martin Meeser
3
Nie jestem pewien, czy specyfikacja HTTP / 2 jest właściwym miejscem do podania szczegółowych informacji o pochodzeniu HTTP / 2 i tym, czym różni się od websocket. Można jednak łatwo zauważyć, że w przypadku HTTP / 2 korzystamy z komunikacji dwukierunkowej: goo.gl/IJVxWS (strony 6 i 13)
Guillaume D.
27
HTTP / 2 jest rzeczywiście dwukierunkowy, ale nie symetryczny, co oznacza, że ​​tylko klient może wysłać właściwe żądanie, a serwer może wysłać odpowiedzi i obietnice żądania (push). To sprawia, że ​​gniazda sieciowe różnią się tym, że obie strony są bardziej „równe” pod względem tego, co wolno im wysyłać / odbierać.
George Antoniadis,
3
W IEEE Software Engineering Radio znajduje się doskonały podcast na temat pochodzenia HTTP2. Myślę, że to jest to: se-radio.net/2015/07/episode-232-mark-nottingham-on-http2
Max Murphy
2
podobną odpowiedź z pełnym uzasadnieniem można znaleźć w tym artykule InfoQ tutaj: infoq.com/articles/websocket-and-http2-coexist
mantrid
151

Po zakończeniu czytania specyfikacji HTTP / 2 myślę, że HTTP / 2 robi przestarzałe gniazda sieciowe dla większości przypadków użycia, ale może nie wszystkie.

PUSH_PROMISE(potocznie znany jako push serwera) nie jest tutaj problemem. To tylko optymalizacja wydajności.

Głównym przypadkiem użycia Websockets w przeglądarce jest umożliwienie dwukierunkowego przesyłania danych. Myślę więc, że pytanie PO brzmi, czy HTTP / 2 lepiej radzi sobie z włączaniem dwukierunkowego przesyłania strumieniowego w przeglądarce i myślę, że tak.

Przede wszystkim jest to bi-di. Wystarczy przeczytać wprowadzenie do sekcji strumieni :

„Strumień” to niezależna, dwukierunkowa sekwencja ramek wymienianych między klientem a serwerem w ramach połączenia HTTP / 2. Strumienie mają kilka ważnych cech:

Pojedyncze połączenie HTTP / 2 może zawierać wiele jednocześnie otwartych strumieni, z ramkami przeplatającymi punkty końcowe z wielu strumieni.

Strumienie mogą być ustanawiane i używane jednostronnie lub współdzielone przez klienta lub serwer.

Strumienie mogą być zamykane przez dowolny punkt końcowy.

Artykuły takie jak ten (połączone w innej odpowiedzi) są błędne na temat tego aspektu HTTP / 2. Mówią, że to nie bidi. Spójrz, jest jedna rzecz, która nie może się zdarzyć z HTTP / 2: Po otwarciu połączenia serwer nie może zainicjować zwykłego strumienia, tylko strumień push. Ale gdy klient otworzy strumień, wysyłając żądanie, obie strony mogą w dowolnym momencie wysłać ramki DATA przez trwałe gniazdo - pełne bidi.

Nie różni się to zbytnio od websockets: klient musi zainicjować żądanie aktualizacji websocket, zanim serwer będzie mógł również przesyłać dane.

Największą różnicą jest to, że w przeciwieństwie do gniazd sieciowych, HTTP / 2 definiuje własną semantykę multipleksowania: w jaki sposób strumienie uzyskują identyfikatory i jak ramki przenoszą identyfikator strumienia, w którym się znajdują. HTTP / 2 definiuje również semantykę kontroli przepływu w celu ustalania priorytetów strumieni. Jest to ważne w większości rzeczywistych zastosowań bidi.

(Ten zły artykuł mówi również, że standard Websocket ma multipleksowanie. Nie, nie ma. Nie jest to trudne do znalezienia, po prostu otwórz Websocket RFC 6455 i naciśnij ⌘-F i wpisz „multipleks”. Po przeczytaniu

Protokół ma być rozszerzalny; przyszłe wersje prawdopodobnie wprowadzą dodatkowe koncepcje, takie jak multipleksowanie.

Przekonasz się, że istnieje rozszerzenie wersji roboczej 2013 dla multipleksowania Websocket. Ale nie wiem, które przeglądarki obsługują to. Nie próbowałbym zbudować mojej aplikacji SPA z tyłu tego rozszerzenia, zwłaszcza gdy nadchodzi HTTP / 2, wsparcie może nigdy nie dotrzeć.

Multipleksowanie jest dokładnie tym, co zwykle musisz zrobić sam za każdym razem, gdy otworzysz websocket dla bidi, powiedzmy, aby zasilić reagująco aktualizującą aplikację na jednej stronie. Cieszę się, że jest w specyfikacji HTTP / 2, o którą zadbano raz na zawsze.

Jeśli chcesz wiedzieć, co potrafi HTTP / 2, po prostu spójrz na gRPC. gRPC jest zaimplementowany w HTTP / 2. Przyjrzyj się w szczególności opcji przesyłania strumieniowego w trybie half i full duplex, które oferuje gRPC. (Należy pamiętać, że gRPC obecnie nie działa w przeglądarkach, ale jest tak naprawdę dlatego, że przeglądarki (1) nie ujawniają ramki HTTP / 2 w javascript klienta i (2) zasadniczo nie obsługują zwiastunów, które są używane w specyfikacja gRPC).

Gdzie wciąż mogą znajdować się gniazda sieciowe? Duży z nich to dane binarne wypychane przez serwer-> przeglądarka. HTTP / 2 pozwala na wypychanie danych binarnych przez serwer-> przeglądarka, ale nie jest ujawnione w JS przeglądarki. W przypadku takich aplikacji, jak wypychanie ramek audio i wideo, jest to powód do korzystania z gniazd sieciowych.

Edycja: 17 stycznia 2020 r

Z czasem ta odpowiedź stopniowo rosła do góry (co jest dobre, ponieważ ta odpowiedź jest mniej więcej poprawna). Jednak wciąż pojawiają się sporadyczne komentarze mówiące, że z różnych powodów nie jest to poprawne, zwykle związane z pewnym zamieszaniem na temat PUSH_PROMISEtego, jak faktycznie konsumować serwer zorientowany na wiadomości -> wypychanie klienta w aplikacji na jednej stronie. Istnieje również przypadek użycia dla websockets w przeglądarce, która jest danymi binarnymi przekazywanymi przez serwer. W przypadku danych tekstowych, w tym JSON, nie używaj gniazd sieciowych, użyj SSE.

Reasumując: protokół HTTP / 2 jest pełny bi-di. Jednak nowoczesne przeglądarki internetowe nie narażają zorientowanego na ramki protokołu HTTP / 2 na JavaScript . Niemniej jednak, jeśli wysyłasz wiele żądań do tego samego źródła przez połączenie HTTP / 2, pod maską cały ten ruch jest multipleksowany na jednym połączeniu (i właśnie o to nam chodzi!).

Więc jeśli chcesz zbudować aplikację do czatowania w czasie rzeczywistym, powiedzmy, gdzie musisz rozgłaszać nowe wiadomości czatu do wszystkich klientów w pokoju czatu, którzy mają otwarte połączenia, możesz (i prawdopodobnie powinien) zrobić to bez gniazd internetowych.

Używałbyś zdarzeń wysłanych przez serwer do wypychania wiadomości w dół, a aplet Fetch do wysyłania żądań w górę. Server-Sent Events (SSE) to mało znany, ale dobrze obsługiwany interfejs API, który udostępnia zorientowany na komunikaty strumień serwer-klient. Chociaż nie wygląda to tak w kliencie JavaScript, pod maską twoja przeglądarka (jeśli obsługuje HTTP / 2) ponownie użyje jednego połączenia TCP do multipleksowania wszystkich tych wiadomości. Nie ma utraty wydajności i w rzeczywistości jest to zysk w stosunku do gniazd sieciowych. Potrzebujesz wielu strumieni? Otwórz wiele źródeł zdarzeń! Zostaną dla Ciebie automatycznie zmultipleksowane.

Oprócz tego, że są bardziej wydajne pod względem zasobów i mają mniejsze opóźnienie początkowe niż uścisk strony internetowej, zdarzenia wysyłane przez serwer mają dobrą właściwość polegającą na tym, że automatycznie się wycofują i działają na HTTP / 1.1. Ale gdy masz połączenie HTTP / 2, działają one niesamowicie dobrze.

Oto dobry artykuł z przykładem realnego aktualizowania SPA.

masonk
źródło
21
Ta odpowiedź częściowo nie zgadza się z innymi, w tym z zaakceptowaną, i jest to również najlepsza odpowiedź, ponieważ jest oparta na bezpośrednich źródłach.
sudo
7
W pełni zgadzam się z tą odpowiedzią i komentarzem. HTTP / 2 jest dwukierunkowy w trybie strumieniowym.
Martin Meeser,
3
Właściwie poprawna odpowiedź, facet zadał sobie trud sprawdzenia źródeł i aplikacji w świecie rzeczywistym (grpc)
Vladimir Akopyan,
1
W websockets serwer nie może rozpocząć wypychania dowolnych bajtów, dopóki klient nie zainicjuje żądania aktualizacji websocket, ale wtedy może przesłać w dowolnym momencie. W HTTP / 2 serwer nie może rozpocząć wypychania bajtów, dopóki klient nie zainicjuje połączenia danych, ale wtedy może przesyłać bajty w dowolnym momencie. Jaka jest funkcjonalna różnica? Jak już wspomniałem, funkcja PUSH_PROMISE to czerwony śledź. To nie jest powód, dla którego HTTP / 2 zastępuje gniazda sieciowe. Jest to tylko niewielka optymalizacja wydajności z boku. Nie ma to nic wspólnego z sercem HTTP / 2, jakim jest streaming BiDi.
masonk,
1
Ta odpowiedź jest po prostu błędna. Mylą tak wiele aspektów, że łatwo ją pomylić. Sedno sprawy polega jednak na tym, że strumienie HTTP / 2 „bidi” są sterowane odpowiedzią na żądanie (i mają ograniczoną liczbę), podczas gdy protokół WebSockets jest prawdziwym protokołem bidi opartym na wiadomości (nie jest oparty na odpowiedzi na żądanie, z wyjątkiem fazy uzgadniania). Jest to ogromna różnica, której nie można pokonać jedynie przez błędne odczytanie specyfikacji (jak wydaje się, że @masonk zrobił to przypadkowo).
Myst
64

Mówię „nie” ( gniazda sieciowe nie są przestarzałe ).

Pierwszym i najczęściej ignorowanym problemem jest to, że wypychanie HTTP / 2 nie jest egzekwowalne i może być ignorowane przez serwery proxy, routery, innych pośredników, a nawet przeglądarkę.

tj. (z wersji roboczej HTTP2):

Pośrednik może odbierać wypychania z serwera i nie przesyłać ich dalej do klienta . Innymi słowy, jak wykorzystać przekazane informacje, zależy od tego pośrednika. Podobnie pośrednik może zdecydować się na wykonanie dodatkowych wypychań do klienta, bez żadnego działania ze strony serwera.

Dlatego HTTP / 2 Push nie może zastąpić WebSockets.

Ponadto połączenia HTTP / 2 zamykają się po pewnym czasie.

Prawdą jest, że standard stanowi, że:

Połączenia HTTP / 2 są trwałe. Aby uzyskać najlepszą wydajność, oczekuje się, że klienci nie będą zamykać połączeń, dopóki nie zostanie ustalone, że dalsza komunikacja z serwerem nie jest konieczna (na przykład, gdy użytkownik opuści określoną stronę internetową) lub dopóki serwer nie zamknie połączenia.

Ale...

Zachęca się serwery do utrzymywania otwartych połączeń tak długo, jak to możliwe, ale w razie potrzeby wolno im zakończyć połączenia bezczynne . Gdy dowolny punkt końcowy zdecyduje się zamknąć połączenie TCP warstwy transportowej, końcowy punkt końcowy POWINIEN najpierw wysłać ramkę GOAWAY (sekcja 6.8), aby oba punkty końcowe mogły niezawodnie określić, czy poprzednio wysłane ramki zostały przetworzone i z wdziękiem ukończyć lub zakończyć wszelkie niezbędne pozostałe zadania.

Nawet jeśli to samo połączenie pozwala na wypychanie zawartości, gdy jest ona otwarta, a nawet jeśli HTTP / 2 rozwiązuje niektóre problemy z wydajnością wprowadzone przez utrzymywanie aktywności HTTP / 1.1 ... Połączenia HTTP / 2 nie są otwarte przez czas nieokreślony .

Strona internetowa nie może również ponownie zainicjować połączenia HTTP / 2 po zamknięciu (chyba że powrócimy do ciągłego pobierania).

EDYCJA (2017, dwa lata później)

Implementacje HTTP / 2 pokazują, że wiele kart / okien przeglądarki współdzieli jedno połączenie HTTP / 2, co oznacza, że pushnigdy nie będzie wiedział, do której karty / okna należy, eliminując użycie pushjako zamiennika Websockets.

EDYCJA (2020)

Nie jestem pewien, dlaczego ludzie zaczęli głosować za odpowiedzią. Jeśli już, to lata, które upłynęły od opublikowania odpowiedzi, wykazały, że HTTP / 2 nie może zastąpić WebSockets i nie został do tego przeznaczony.

To prawda, że ​​do tunelowania połączeń WebSocket można użyć HTTP / 2 , ale te tunelowane połączenia nadal będą wymagały protokołu WebSocket i wpłyną na sposób działania kontenera HTTP / 2.

Mist
źródło
4
Gniazda WS również nie pozostaną otwarte na zawsze. Różnice dotyczą strumieni; HTTP / 2 zapewnia wiele przepływów strumieniowych, co oznacza, że ​​kontrola przepływu na serwerze jest bardzo różna i często bez blokady. WS (jako protokół) musi mieć nieuregulowane przetwarzanie danych przychodzących. Kontrola przepływu jest realizowana wyżej w górę stosu. Pod względem bezpieczeństwa i integralności serwera HTTP / 2 jest znacznie lepszy niż WS.
obligacja
3
@bond, zgadzam się, że HTTP / 2 ma wiele zalet jako warstwa transportowa (współdzielenie jednego połączenia na wielu kartach przeglądarki to tylko jeden przykład). Jednak nie jest zaprojektowany jako warstwa komunikacyjna . To pytanie funkcjonalne. Oba protokoły odpowiadają różnym potrzebom. tzn. implementacja sshterminala w przeglądarce to pestka przy korzystaniu z Websockets. Byłoby to całkowity ból głowy na HTTP / 2, szczególnie jeśli więcej niż jedna karta jest otwarta. A co jeśli przeglądarka (lub jeden z serwerów proxy HTTP / 2) zamknie połączenie? Czy klient może po prostu założyć, że nowe dane nie są dostępne? wróciliśmy do głosowania.
Myst
1
Przeglądarka może równie łatwo zamknąć połączenie WS. To jest życie z każdym rodzajem sieci. Szczerze mówiąc, multipleksowanie w HTTP / 2 to przesada. Protokół naprawdę go nie potrzebował. Po otwarciu wielu strumieni zaczynasz napotykać problemy z buforami TCP ograniczającymi przepustowość. Zgadzam się z tobą, że WS jest lepszy w tym, co robi, niż HTTP / 2. Zasadniczo WS jest czymś, co wymaga wielu mechanizmów kontroli wyższego poziomu, aby uniemożliwić użytkownikom robienie złych rzeczy.
obligacja
2
Cytując wuja Bena (Spider-Man): „Pamiętaj, że z wielką mocą wiąże się wielka odpowiedzialność”. Tak, @bond, masz rację. Websockets, będące bardzo „surowym” protokołem, wymagają bardziej odpowiedzialnego projektu serwera. I tak, WS można zamknąć tak łatwo jak HTTP / 2, ale WS obsługuje oncloseoddzwanianie, więc odpytywanie nie jest konieczne. Jeśli chodzi o multipleksowanie, myślę, że był to raczej wybór niż wybór. keep-alivenie powiodło się, a jedynym sposobem uniknięcia trafienia „pierwszego w linii” było ryzyko multipleksowania. Czas pokaże :)
Myst
1
Z punktu widzenia projektu serwera multipleksowanie danych wychodzących jest skomplikowanym i kosztownym problemem. Wymaga od mechaników IO sondowania wewnętrznego, co jest drogie jak diabli. O ile nie przesyłasz strumieniowo dużych dokumentów, multipleksowanie nawet nie będzie działać, ponieważ prawdopodobnie prawdopodobnie odpowiedź zostanie całkowicie buforowana wewnętrznie, zanim drugie stanie się dostępne, a multipleksowanie nie uruchomi się. RTMP ma wychodzące multipleksowanie, ale robi to tylko serwer Adobe. To niesamowite, jak blisko HTTP / 2 jest do RTMP.
obligacja
39

Odpowiedź brzmi nie. Cel między nimi jest bardzo różny. Istnieje nawet RFC dla WebSocket przez HTTP / 2, który pozwala na tworzenie wielu połączeń WebSocket za pomocą pojedynczego potoku HTTP / HTTP.

WS przez HTTP / 2 będzie grą oszczędzającą zasoby, skracając czas otwierania nowych połączeń i pozwalając na więcej kanałów komunikacji bez dodatkowego kosztu większej liczby gniazd, miękkich przerw IRQ i buforów.

https://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01

więź
źródło
To jest wspaniałe! Czy istnieje jakiś publiczny przykład klienta Javascript, który to zaimplementował? Nie mogę znaleźć żadnych przykładów. Co powinienem zrobić? Czy to dobry zasób? undertow.io/blog/2015/04/27/An-in-depth-overview-of-HTTP2.html
RaisinBranCrunch
Czy ktoś zna źródło powyższych twierdzeń o 1) znalezieniu długości nagłówka, 2) dolnej obudowie nazw pól?
Pim Heijden,
@PimHeijden wykrywający długość nagłówka w HTTP / 1.x wymaga zapętlenia wszystkich bajtów w poszukiwaniu 4-bajtowego znacznika końcowego. To jest bardzo drogie. Rozróżnianie wielkości liter w nazwach pól oznacza również, że każde dopasowanie pola musi być wykonane zarówno dla wersji wielkiej, jak i małej litery. Wymaga to znajomości całego zestawu znaków do wielkich i małych liter do kontroli. W wersji 2.x można założyć, że są małe.
obligacja
@RaisinBranCrunch Nie możesz kontrolować tego z poziomu Javascript. Przeglądarka zrobi wszystko za Ciebie.
obligacja
@bond Obecnie używam HTTP / 2 z Nginx i proxy_pass do wysyłania połączeń websocket do serwera gniazd, ale gdy jeden użytkownik otwiera wiele kart w witrynie, serwer gniazd traktuje to jako wiele połączeń. Zakładam, że jeśli HTTP / 2 multipleksuje połączenia przez jeden potok TCP, serwer traktuje to jako jedno połączenie. Czy to źle? Czy jest jakiś sposób na sprawdzenie, czy serwer nie wykonuje dodatkowych niepotrzebnych połączeń?
RaisinBranCrunch
23

Cytując ten artykuł InfoQ :

Cóż, odpowiedź jest oczywista, że ​​nie, z prostego powodu: Jak widzieliśmy powyżej, HTTP / 2 wprowadza Server Push, który umożliwia serwerowi proaktywne wysyłanie zasobów do pamięci podręcznej klienta. Nie pozwala to jednak na przekazywanie danych do samej aplikacji klienckiej. Wypychania serwera są przetwarzane tylko przez przeglądarkę i nie wyskakują do kodu aplikacji, co oznacza, że ​​nie ma interfejsu API dla aplikacji, aby otrzymywać powiadomienia o tych zdarzeniach.

W ten sposób push HTTP2 jest naprawdę czymś pomiędzy twoją przeglądarką a serwerem, podczas gdy Websockets naprawdę ujawniają interfejsy API, które mogą być używane zarówno przez klienta (javascript, jeśli działa w przeglądarce), jak i kod aplikacji (uruchomiony na serwerze) do przesyłania danych w czasie rzeczywistym.

Jeet Prakash
źródło
5

Wymiana wiadomości i proste przesyłanie strumieniowe (nie audio, wideo) może odbywać się zarówno przez multipleksowanie HTTP / 2, jak i WebSockets. Więc niektóre nakładają się, ale WebSockets mają dobrze ustalony protokół, wiele frameworków / API i mniej nagłówków. Oto fajny artykuł na ten temat .

Dennis R
źródło
2

Będzie implementacja WebSocket w HTTP / 2. https://tools.ietf.org/html/rfc8441

Dzintary
źródło
Nie, nie będzie ... połączenie WebSocket zostanie tunelowane przez HTTP / 2, ale HTTP / 2 nie zastąpi protokołu ani nie stanie się przestarzały.
Myst
@Myst Czy to powiedziałem?
Dzintars
2
Nie, nie powiedziałeś tego, ja powiedziałem. Napisałeś, że w HTTP / 2 będzie implementacja WebSocket, która IMHO wydawała się zbyt krótka i nieco myląca z powodu pominięcia ważnych szczegółów.
Myst
2

Na razie kwiecień 2020 r. Protokół HTTP / 2 nie powoduje, że WebSockets stają się przestarzałe. Największą zaletą WebSockets nad HTTP2 jest to

HTTP/2 works only on Browser Level not Application Level

Oznacza, że ​​HTTP / 2 nie oferuje żadnego interfejsu API JS, takiego jak WebSockets, umożliwiającego komunikację i transfer pewnego rodzaju JSON lub innych danych na serwer bezpośrednio z aplikacji (np. Strony internetowej). Tak więc, o ile uważam, HTTP / 2 sprawi, że WebSockets stanie się przestarzałe, jeśli zacznie oferować API takie jak WebSockets do komunikacji z serwerem. Do tego czasu jest to tylko zaktualizowana i szybsza wersja HTTP 1.1.

Przewiewny
źródło
2

Na dzień dzisiejszy nie.

HTTP / 2, w porównaniu do HTTP, pozwala na utrzymanie połączenia z serwerem. Stamtąd możesz mieć wiele strumieni danych jednocześnie. Chodzi o to, że możesz pchać wiele rzeczy jednocześnie, nawet bez żądania klienta. Na przykład, gdy przeglądarka prosi o index.html, serwer może chcieć również nacisnąć index.cssiindex.js . Przeglądarka nie poprosiła o to, ale serwer może to zrobić bez pytania, ponieważ może założyć, że będziesz chciał za kilka sekund.

Jest to szybciej niż HTTP / 1 alternatywę uzyskiwania index.html, analizowania go, odkrywając to potrzebuje index.jsi index.css, a następnie blok 2 inne wnioski o tych plikach. HTTP / 2 pozwala serwerowi przesyłać dane, o które klient nawet nie prosił.

W tym kontekście jest podobny do WebSocket, ale nie jest tak naprawdę z założenia. WebSocket powinien umożliwiać dwukierunkową komunikację podobną do połączenia TCP lub połączenia szeregowego. To gniazdo, w którym oboje komunikują się ze sobą. Główna różnica polega także na tym, że można wysyłać dowolne pakiety danych w nieprzetworzonych bajtach, a nie w postaci protokołu HTTP. Pojęcia nagłówków, ścieżek i ciągów zapytań występują tylko podczas uzgadniania, ale WebSocket otwiera strumień danych.

Inną różnicą jest to, że uzyskujesz o wiele bardziej precyzyjny dostęp do WebSocket w JavaScript, podczas gdy w przypadku HTTP jest on obsługiwany przez przeglądarkę. Wszystko, co zyskujesz dzięki HTTP, to wszystko, co możesz zmieścić w XHR/ fetch(). Oznacza to również, przeglądarka będzie dostać się przechwycić i zmodyfikować nagłówki HTTP bez ciebie jest w stanie go kontrolować (np Origin, Cookiesitp). Ponadto to, co HTTP / 2 jest w stanie wypchnąć, jest wysyłane do przeglądarki. Oznacza to, że JS nie zawsze (jeśli w ogóle) wie, że wszystko jest popychane. Ponownie, ma to sens index.cssi index.jsponieważ przeglądarka go buforuje, ale nie tyle pakietów danych.

To naprawdę wszystko w nazwie. HTTP oznacza HyperText Transfer Protocol. Koncentrujemy się na koncepcji przenoszenia aktywów. WebSocket polega na budowaniu połączenia przez gniazdo, w którym dane binarne są przekazywane dwukierunkowo.


Tym, o którym tak naprawdę nie rozmawiamy, jest SSE (zdarzenia wysyłane przez serwer). Przekazywanie danych do aplikacji (JS) nie jest intencją HTTP / 2, ale dotyczy SSE. SSE zostaje naprawdę wzmocnione dzięki HTTP / 2. Ale nie jest to prawdziwy zamiennik dla WebSockets, gdy ważne są same dane, a nie osiągane zmienne punkty końcowe. Dla każdego punktu końcowego w WebSocket tworzony jest nowy strumień danych, ale w SSE jest on dzielony między już istniejącą sesją HTTP / 2.


Podsumowano tutaj cele dla każdego:

  • HTTP - odpowiedz na żądanie za pomocą jednego zasobu
  • HTTP / 2 - odpowiedz na zapytanie z wieloma zasobami
  • SSE - Odpowiedz z jednokierunkowym strumieniem zdarzeń tekstu (UTF-8)
  • WebSocket - Utwórz dwukierunkowy strumień danych binarnych
ShortFuse
źródło