Po co korzystać z AJAX, gdy WebSockets jest dostępny?

203

Od jakiegoś czasu korzystam z WebSockets, postanowiłem stworzyć narzędzie do zarządzania projektami Agile dla mojego ostatniego roku na Uniwersytecie, używając serwera Node i WebSockets. Odkryłem, że używanie WebSockets zapewnia wzrost liczby żądań o 624% na sekundę, które moja aplikacja może przetworzyć.

Jednak od rozpoczęcia projektu czytałem o lukach bezpieczeństwa i niektóre przeglądarki domyślnie wyłączają WebSockets ..

To prowadzi mnie do pytania:

Po co korzystać z AJAX, gdy WebSockets wydaje się wykonywać tak wielką robotę, zmniejszając opóźnienia i koszty ogólne zasobów, czy jest coś, co AJAX robi lepiej niż WebSockets?

Jacek
źródło
2
Oto lista silników obsługujących gniazda sieciowe. en.wikipedia.org/wiki/…
Dante

Odpowiedzi:

209

WebSockets nie ma na celu zastąpienia AJAX i nie jest nawet zamiennikiem komety / długiego odpytywania (chociaż w wielu przypadkach ma to sens).

Celem WebSockets jest zapewnienie dwukierunkowego, pełnego dupleksu i długotrwałego połączenia między przeglądarką a serwerem o niskim opóźnieniu. WebSockets otwiera nowe domeny aplikacji dla aplikacji przeglądarki, które tak naprawdę nie były możliwe przy użyciu HTTP i AJAX (gry interaktywne, dynamiczne strumienie mediów, mostkowanie z istniejącymi protokołami sieciowymi itp.).

Z pewnością jednak WebSockets i AJAX / Comet nakładają się na siebie. Na przykład, gdy przeglądarka chce być powiadamiana o zdarzeniach serwera (tj. Push), wówczas techniki Comet i WebSockets są z pewnością realnymi opcjami. Jeśli Twoja aplikacja potrzebuje zdarzeń wypychających o niskim opóźnieniu, byłoby to czynnikiem przemawiającym za WebSockets. Z drugiej strony, jeśli musisz współistnieć z istniejącymi frameworkami i wdrożonymi technologiami (OAuth, RESTful APIs, proxy, równoważenie obciążenia), to byłby to czynnik na korzyść technik Comet (na razie).

Jeśli nie potrzebujesz konkretnych korzyści zapewnianych przez WebSockets, prawdopodobnie lepiej jest trzymać się istniejących technik, takich jak AJAX i Comet, ponieważ pozwala to na ponowne użycie i integrację z ogromnym istniejącym ekosystemem narzędzi, technologii, mechanizmów bezpieczeństwa , bazy wiedzy (tj. znacznie więcej osób korzystających z stackoverflow zna HTTP / Ajax / Comet niż WebSockets) itp.

Z drugiej strony, jeśli tworzysz nową aplikację, która po prostu nie działa dobrze w granicach opóźnień i ograniczeń połączenia HTTP / Ajax / Comet, rozważ użycie WebSockets.

Ponadto niektóre odpowiedzi wskazują, że jedną z wad WebSockets jest ograniczona / mieszana obsługa serwerów i przeglądarek. Pozwól mi to trochę rozproszyć. Podczas gdy iOS (iPhone, iPad) nadal obsługuje starszy protokół (Hixie), większość serwerów WebSockets obsługuje zarówno Hixie, jak i wersję HyBi / IETF 6455 . Większość innych platform (jeśli nie ma jeszcze wbudowanej obsługi) może uzyskać obsługę WebSockets za pośrednictwem web-socket-js (wielouzupełnianie oparte na Flashu). Obejmuje to zdecydowaną większość użytkowników sieci. Ponadto, jeśli używasz Węzła jako backendu serwera, rozważ użycie Socket.IO, który zawiera web-socket-js jako awarię, a jeśli nawet to nie jest dostępne (lub wyłączone), wróci do korzystania z dowolnej techniki Comet dostępne dla danej przeglądarki.

Aktualizacja : iOS 6 obsługuje teraz obecny standard HyBi / IETF 6455.

kanaka
źródło
37
A teraz na początku 2014 r. WebSockets jest praktycznie standardem (RFC 6455) i tylko Opera mini go nie obsługuje.
Dirk Bester
4
To prawda, że ​​Opera Mini go nie obsługuje, ale bardziej zawstydzający jest brak obsługi przeglądarki Androida, co sprawia, że ​​korzystanie z aplikacji opartych na webview (Cordova PhoneGap) jest nieco bardziej skomplikowane
Miles M.
2
@kanaka, jeśli oba z nich robią duże pliki równie dobrze, to dlaczego nie wysłać wszystkiego za pośrednictwem gniazd sieciowych? Po co zawracać sobie głowę stronami / danymi, skoro wszystko można wysłać przez WebSockets? (Załóżmy, że jest to już rok 2020 i wszystkie przeglądarki obsługują WebSockets)
Pacerier
3
@Pacerier pełna odpowiedź byłaby długa, ale w zasadzie sprowadza się do tego, że próbujesz ponownie wdrożyć rzeczy, które przeglądarka już dobrze sobie radzi (buforowanie, bezpieczeństwo, równoległość, obsługa błędów itp.). Jeśli chodzi o wydajność, chociaż szybkość przesyłania dużych plików od zera byłaby podobna, przeglądarki mają lata na dokładne dostrojenie buforowania treści internetowych (z których większość dotyczy żądań AJAX), więc w praktyce przejście z AJAX na WebSockets raczej nie zapewni dużo korzyści dla istniejącej funkcjonalności. Ale dla dwukierunkowej komunikacji o niskim opóźnieniu jest to ogromna wygrana.
kanaka
5
Przepraszam, ale dla mnie to nie odpowiada na pytanie. Zasadniczo mówi tylko, że nie mają na celu wzajemnego zastępowania i że WS nie jest w pełni obsługiwany (jest teraz). Nie odpowiada, dlaczego wolisz AJAX od websocket? Weźmy na przykład Discord. Discord używa WS do przesyłania wiadomości i zdarzeń z serwera do klientów, tymczasem wykorzystuje żądania HTTP od klienta do serwera (wysyłanie wiadomości, danych żądań itp.). Przyszedłem do tego pytania, aby uzyskać odpowiedź, dlaczego to zrobiłeś. Czy istnieje jakiś techniczny powód, dla którego chciałbyś umieścić AJAX ponad otwartym połączeniem WS?
Charlotte Dunois,
63

Do przodu w grudniu 2017 r. Websockets są obsługiwane przez (praktycznie) każdą przeglądarkę, a ich użycie jest bardzo powszechne.

Nie oznacza to jednak, że Websockets udało się zastąpić AJAX, przynajmniej nie do końca, zwłaszcza gdy rośnie liczba adaptacji HTTP / 2.

Krótka odpowiedź jest taka, że ​​AJAX jest nadal świetny dla większości aplikacji REST, nawet przy użyciu Websockets. Ale Bóg tkwi w szczegółach, więc ...:

AJAX do odpytywania?

Korzystanie z AJAX do odpytywania (lub długiego odpytywania) wymiera (i powinno być), ale nadal jest używane z dwóch dobrych powodów (głównie w przypadku mniejszych aplikacji internetowych):

  1. Dla wielu programistów AJAX jest łatwiejszy do kodowania, szczególnie jeśli chodzi o kodowanie i projektowanie backendu.

  2. Dzięki HTTP / 2 wyeliminowano najwyższy koszt związany z AJAX (ustanowienie nowego połączenia), dzięki czemu połączenia AJAX są dość wydajne, szczególnie w przypadku wysyłania i przesyłania danych.

Jednak wypychanie Websocket jest znacznie lepsze niż AJAX (nie trzeba ponownie uwierzytelniać ani ponownie wysyłać nagłówków, nie ma potrzeby robienia objazdów „bez danych” itp.). Zostało to wielokrotnie omówione .

AJAX dla REST?

Lepszym zastosowaniem dla AJAX są wywołania interfejsu API REST. Takie użycie upraszcza bazę kodu i zapobiega blokowaniu połączenia Websocket (szczególnie przy przesyłaniu danych średniej wielkości).

Istnieje wiele istotnych powodów, aby preferować AJAX do wywołań interfejsu API REST i przesyłania danych:

  1. Interfejs API AJAX został praktycznie zaprojektowany do wywołań interfejsu API REST i jest doskonale dopasowany.

  2. Wywołania REST i przesyłanie za pomocą AJAX są znacznie łatwiejsze do kodowania, zarówno na kliencie, jak i backend.

  3. W miarę wzrostu ładunku danych połączenia Websocket mogą zostać zablokowane, chyba że zakodowana zostanie logika fragmentacji / multipleksowania wiadomości.

    Jeśli przesyłanie jest wykonywane w pojedynczym sendwywołaniu Websocket , może on blokować strumień Websocket, dopóki przesyłanie nie zostanie zakończone. Spowoduje to zmniejszenie wydajności, szczególnie w przypadku wolniejszych klientów.

Wspólny projekt wykorzystuje małe wiadomości bidi przesyłane przez Websockets, podczas gdy REST i przesyłanie danych (klient do serwera) wykorzystują łatwość użycia AJAX, aby zapobiec blokowaniu Websocket.

Jednak w większych projektach elastyczność oferowana przez Websockets i równowaga między złożonością kodu a zarządzaniem zasobami przechyli równowagę na korzyść Websockets.

Na przykład przesyłanie oparte na Websocket może oferować możliwość wznowienia dużych przesyłania po zerwaniu połączenia i ponownym nawiązaniu połączenia (pamiętasz film 5 GB, który chcesz przesłać?).

Kodując logikę fragmentacji wysyłania, łatwo jest wznowić przerwane przesyłanie (trudna część to kodowanie).

Co z push / HTTP?

Powinienem chyba dodać, że funkcja push HTTP / 2 nie zastępuje (i prawdopodobnie nie może) zastąpić Websockets.

Zostało to już wcześniej omówione , ale wystarczy wspomnieć, że pojedyncze połączenie HTTP / 2 obsługuje całą przeglądarkę (wszystkie karty / okna), więc dane wypychane przez HTTP / 2 nie wiedzą, do której karty / okna należy, eliminując jego zdolność do zastępowania zdolności Websocket do przekazywania danych bezpośrednio do określonej karty / okna przeglądarki.

Podczas gdy Websockets świetnie nadają się do małych dwukierunkowych transmisji danych, AJAX wciąż ma wiele zalet - zwłaszcza przy rozważaniu większych ładunków (przesyłanie itp.).

A bezpieczeństwo?

Cóż, ogólnie, im więcej zaufania i kontroli zapewnia programista, tym potężniejsze narzędzie ... i tym więcej obaw związanych z bezpieczeństwem.

AJAX z natury miałby przewagę, ponieważ jego bezpieczeństwo jest wbudowane w kod przeglądarki (co czasem jest wątpliwe, ale nadal istnieje).

Z drugiej strony, wywołania AJAX są bardziej podatne na ataki typu „man in the middle”, podczas gdy problemy z bezpieczeństwem Websockets są zwykle błędami w kodzie aplikacji, które wprowadziły lukę w zabezpieczeniach (zwykle tam znajduje się logika uwierzytelniania zaplecza).

Osobiście nie uważam, żeby była to wielka różnica, jeśli myślę, że Websockets są nieco lepsze, szczególnie gdy wiesz, co robisz.

Moja skromna opinia

IMHO, używałbym Websockets do wszystkiego oprócz wywołań interfejsu API REST. Przesyłanie dużych danych Chciałbym fragmentować i wysyłać przez Websockets, jeśli to możliwe.

Sondowanie, IMHO, powinno być zakazane, koszt ruchu sieciowego jest okropny, a wypychanie Websocket jest wystarczająco łatwe do zarządzania nawet dla nowych programistów.

Mist
źródło
2
Mały błąd gramatyczny „jeśli coś mi się podoba ...”, myślę 😀
spottedmahn
2
@spottedmahn - Dzięki! Wydaje mi się, że tak się dzieje. Korzystam z mojego edytora kodu do szkicowania tekstu 🙃
Myst
1
Przepraszam, byłem nieobecny, gdy wygasła nagroda. Złe planowanie z mojej strony. Ustawiłem kolejną nagrodę, którą przyznam ci po upływie 23 godzin.
Duncan Jones
@ Mistyczne podziękowania za to świetne wyjaśnienie. Co wolisz w przypadku powiadomień na żywo, takich jak FB / Stackoverflow? Projektuję usługi sieciowe RestFull dla mojej aplikacji internetowej, ale jestem bardzo zdezorientowany, czego powinienem użyć do funkcji powiadomień? AJAX czy WebSockets?
TheCoder
@puspen powiadomienia są (IMHO) idealne dla Websockets. Podczas projektowania logiki ponownego połączenia i kolejek powiadomień offline należy podjąć wiele decyzji, ale faktyczne powiadomienie jest łatwe do kodowania i wydajne dzięki gniazdom internetowym.
Myst
18

Oprócz problemów ze starszymi przeglądarkami (w tym IE9, ponieważ WebSockets będą obsługiwane od IE10), nadal istnieją duże problemy z pośrednikami sieci, którzy jeszcze nie obsługują WebSockets, w tym przezroczyste proxy, odwrotne proxy i usługi równoważenia obciążenia. Istnieje kilku operatorów komórkowych, którzy całkowicie blokują ruch WebSocket (to znaczy po komendzie HTTP UPGRADE).

Z upływem lat WebSockets będą coraz bardziej obsługiwane, ale w międzyczasie zawsze powinieneś mieć opartą na HTTP metodę awaryjną do wysyłania danych do przeglądarek.

Alessandro Alinone
źródło
Na szczęście większość platform WebSocket obsługuje wspomniane awarie, w tym używa Flasha do gniazd. Socketn.IO i SignalR to przyzwoite frameworki ... chociaż jesteś naprawdę ograniczony, jak wspominasz z powodu serwerów proxy i równoważników obciążenia. Na szczęście zarówno Node.JS, jak i następne IIS również wykonują przyzwoitą pracę z tą rolą.
Tracker1
Ciekawe: którzy przewoźnicy blokują WebSocket na porcie 80? Który blok zabezpiecza WebSocket (WSS) na porcie 443? Ta ostatnia implikuje wymuszone, przejrzyste serwery proxy MITM .. nigdy nie widziałem tego w sieciach publicznych (tylko korporacyjnych), ponieważ wymaga instalowania nowych certyfikatów CA w przeglądarkach.
oberstet
Przykład przeciwnika, obecnie Vodafone Włochy blokuje WS na porcie 80, ale zezwala na WSS na porcie 443. Możesz dość łatwo przetestować dowolnego przewoźnika za pośrednictwem naszej strony głównej, do której masz dostęp zarówno w HTTP, jak i HTTPS. Próbuje WebSockets i wraca do HTTP, jeśli są one zablokowane. Użyj tego adresu URL, aby wyświetlić widget pośrodku, który zgłasza aktualny transport: lightstreamer.com/?s
Alessandro Alinone
17

Większość narzekań, które przeczytałem o gniazdach sieciowych i zabezpieczeniach, pochodzi od dostawców zabezpieczeń zabezpieczeń przeglądarek internetowych i narzędzi zabezpieczających zaporę ogniową. Problem polega na tym, że nie wiedzą, jak przeprowadzić analizę bezpieczeństwa ruchu websockets, ponieważ po dokonaniu aktualizacji z HTTP do protokołu binarnego websocket zawartość pakietu i jego znaczenie są specyficzne dla aplikacji (w zależności od tego, co programujesz). Jest to oczywiście logistyczny koszmar dla tych firm, których źródła utrzymania opierają się na analizie i klasyfikacji całego ruchu internetowego. :)

Tim Lovell-Smith
źródło
11

WebSockets nie działają w starszych przeglądarkach internetowych, a te, które go obsługują, często mają różne implementacje. To właściwie jedyny dobry powód, dla którego nie są używane przez cały czas zamiast AJAX.

jli
źródło
8
Lepszym powodem jest to, że żądanie AJAX jest normalnym żądaniem HTTP, co oznacza, że ​​może pobierać zasoby HTTP; WebSockets nie może tego zrobić.
Dan D.
@ Dan Co jeśli na przykład pliki graficzne są wysyłane jako base64, CSS jako tekst, JavaScript również jako tekst, a następnie dołączane do dokumentu? Czy to byłoby prawdopodobne?
Jack
@DanD. +1, zgadzam się, myślę, że podchodziłem do pytania bardziej w kontekście szybkiego przesyłania strumieniowego danych, jak w przykładzie pytania, ale jest to zdecydowanie poprawne.
jli
@Dan D - czasami nie chcesz, żeby te wszystkie bzdury przekraczały
granice
8
@DanD., HTTP i WebSocket to dwa odrębne protokoły. Oczywiście nie możemy żądać zasobów HTTP za pomocą protokołu WebSocket z tego samego powodu, dla którego nie możemy żądać zasobów WebSocket za pomocą protokołu HTTP! Nie oznacza to, że klient nie może żądać plików HTML i / lub obrazów wysłanych za pośrednictwem protokołu Websocket.
Pacerier
2

Nie sądzę, abyśmy mogli dokonać jasnego porównania Websockets i HTTP, ponieważ nie są oni rywalami ani rozwiązać tych samych problemów.

Websockets są doskonałym wyborem do obsługi długotrwałego dwukierunkowego przesyłania danych w sposób zbliżony do czasu rzeczywistego, natomiast REST doskonale nadaje się do okazjonalnej komunikacji. Korzystanie z websockets jest znaczną inwestycją, dlatego jest okazją do nadmiaru w przypadku sporadycznych połączeń.

Może się okazać, że Websockets radzą sobie lepiej, gdy obecne są duże obciążenia, w niektórych przypadkach HTTP jest nieco szybszy, ponieważ może wykorzystywać buforowanie. Porównanie REST z Websockets jest jak porównywanie jabłek z pomarańczami.

Powinniśmy sprawdzić, które z nich zapewnia lepsze rozwiązanie dla naszej aplikacji, które najlepiej pasuje do naszej wygranej.

Gaurav Gandhi
źródło
1
pytanie dotyczyło ogólnie AJAX, a nie REST w szczególności. To prawda, że ​​AJAX może być używany do REST, ale jest również używany do odpytywania i długiego odpytywania. Chociaż zgadzam się z twoją konkluzją (jak możesz stwierdzić z mojej odpowiedzi), myślę, że twoja odpowiedź może odzwierciedlać to rozróżnienie (zwróć uwagę, że Websockets można również wykorzystać do REST, chociaż nie przy użyciu metod HTTP).
Myst
@Myst Zgadzam się z tobą.
Gaurav Gandhi
1

Przykład różnic między HTTP a Websockets w postaci biblioteki wielkości klienta, która może obsługiwać punkt końcowy Websocket, taki jak interfejsy API REST, i punkty końcowe RESTful, takie jak Websockets na kliencie. https://github.com/mikedeshazer/sockrest Także dla tych, którzy próbują korzystać z interfejsu API Websocket na kliencie lub odwrotnie, w sposób, w jaki są przyzwyczajeni. Biblioteka libs / sockrest.js wyraźnie wyjaśnia różnice (a raczej powinna).

Mike D.
źródło