Przeczytałem wiele postów w SO iw Internecie dotyczących słów kluczowych w tytule mojego pytania i wiele się z nich nauczyłem. Niektóre z pytań, które czytam, dotyczą konkretnych wyzwań wdrożeniowych, inne dotyczą ogólnych pojęć. Chcę się tylko upewnić, że zrozumiałem wszystkie koncepcje i powody, dla których wynaleziono technologię X zamiast technologii Y i tak dalej. Więc oto idzie:
Sondowanie HTTP: zasadniczo AJAX, przy użyciu XmlHttpRequest.
Http Long Polling: AJAX, ale serwer wstrzymuje odpowiedź, chyba że serwer ma aktualizację, gdy tylko serwer ma aktualizację, wysyła ją, a następnie klient może wysłać kolejne żądanie. Wadą są dodatkowe dane nagłówka, które muszą być przesyłane tam iz powrotem, powodując dodatkowe obciążenie.
Strumieniowanie HTTP: Podobny do długiego odpytywania, ale serwer odpowiada nagłówkiem „Transfer Encoding: chunked”, a zatem nie musimy inicjować nowego żądania za każdym razem, gdy serwer wysyła jakieś dane (i dlatego zapisuje dodatkowy nagłówek narzutu). Wadą jest to, że musimy „zrozumieć” i wymyślić strukturę danych, aby rozróżnić wiele fragmentów wysyłanych przez serwer.
Aplet Java, Flash, Silverlight: zapewniają możliwość łączenia się z serwerami gniazd przez tcp / ip, ale ponieważ są to wtyczki, programiści nie chcą na nich polegać.
WebSockets: są to nowe API, które próbuje rozwiązać wady powyższych metod w następujący sposób:
- Jedyną zaletą WebSockets w porównaniu z wtyczkami, takimi jak aplety Java, Flash czy Silverlight jest to, że WebSockets są natywnie wbudowane w przeglądarki i nie polegają na wtyczkach.
- Jedyną zaletą WebSockets w porównaniu do przesyłania strumieniowego HTTP jest to, że nie trzeba się wysilać, aby „zrozumieć” i przeanalizować otrzymane dane.
- Jedyną zaletą WebSockets w porównaniu z Long Polling jest eliminacja dodatkowego rozmiaru nagłówków oraz otwieranie i zamykanie połączenia gniazda na żądanie.
Czy są jakieś inne istotne różnice, których mi brakuje? Przepraszam, jeśli ponownie zadaję lub łączę wiele pytań już na SO w jedno pytanie, ale chcę po prostu nadać doskonały sens wszystkim informacjom, które są dostępne w SO i sieci, dotyczące tych koncepcji.
Dzięki!
źródło
Odpowiedzi:
Jest więcej różnic niż te, które zidentyfikowałeś.
Duplex / kierunkowe:
W kolejności rosnącego opóźnienia (przybliżona):
CORS (obsługa wielu źródeł):
Natywne dane binarne (tablice typowane, obiekty blob):
Szerokość pasma przy malejącej wydajności:
Obsługa urządzeń mobilnych:
Złożoność użycia JavaScript (od najprostszych do najbardziej skomplikowanych). Trzeba przyznać, że miary złożoności są nieco subiektywne.
Należy również zauważyć, że istnieje propozycja W3C dotycząca standaryzacji przesyłania strumieniowego HTTP o nazwie Zdarzenia wysyłane przez serwer . Obecnie jest dość wcześnie w swojej ewolucji i został zaprojektowany w celu zapewnienia standardowego interfejsu API JavaScript z porównywalną prostotą do WebSockets.
źródło
Kilka świetnych odpowiedzi od innych, które obejmują wiele zagadnień. Oto trochę więcej.
Jeśli przez to masz na myśli, że możesz użyć apletów Java, Flash lub Silverlight do ustanowienia połączenia przez gniazdo, to tak, to jest możliwe. Jednak nie widzisz tego zbyt często w prawdziwym świecie ze względu na ograniczenia.
Na przykład pośrednicy mogą i wyłączają ten ruch. Standard WebSocket został zaprojektowany tak, aby był kompatybilny z istniejącą infrastrukturą HTTP, dzięki czemu jest znacznie mniej podatny na ingerencję pośredników, takich jak zapory i serwery proxy.
Co więcej, WebSocket może używać portów 80 i 443 bez konieczności stosowania dedykowanych portów, również dzięki projektowi protokołu, który jest możliwie jak najbardziej kompatybilny z istniejącą infrastrukturą HTTP.
Te alternatywy gniazd (Java, Flash i Silverlight) są trudne w bezpiecznym użyciu w architekturze między źródłami. Dlatego ludzie, którzy często próbują ich używać w różnych miejscach, będą tolerować niepewność, zamiast podejmować wysiłki, aby robić to bezpiecznie.
Mogą również wymagać otwarcia dodatkowych „niestandardowych” portów (coś, czego administratorzy nie lubią robić) lub plików zasad, którymi trzeba zarządzać.
Krótko mówiąc, używanie Java, Flash lub Silverlight do łączenia się z gniazdami jest na tyle problematyczne, że nie widać go zbyt często w poważnych architekturach. Flash i Java mają taką możliwość od prawdopodobnie co najmniej 10 lat, a jednak nie są one powszechne.
Standard WebSocket mógł zacząć od nowego podejścia, mając na uwadze te ograniczenia i miejmy nadzieję, że wyciągnął z nich pewne wnioski.
Niektóre implementacje WebSocket używają Flasha (lub prawdopodobnie Silverlight i / lub Java) jako rozwiązania zastępczego, gdy nie można ustanowić łączności WebSocket (na przykład podczas uruchamiania w starej przeglądarce lub gdy przeszkadza pośrednik).
Chociaż jakaś strategia awaryjna w takich sytuacjach jest sprytna, a nawet konieczna, większość tych, którzy używają Flasha i innych, będzie cierpieć z powodu opisanych powyżej wad. Nie musi tak być - istnieją obejścia umożliwiające uzyskanie bezpiecznych połączeń obsługujących różne źródła przy użyciu Flash, Silverlight itp. - ale większość implementacji tego nie zrobi, ponieważ nie jest to łatwe.
Na przykład, jeśli polegasz na protokole WebSocket jako połączenia między źródłami, to zadziała dobrze. Ale jeśli następnie uruchomisz w starej przeglądarce lub włączysz zaporę ogniową / serwer proxy i polegasz na Flash, powiedzmy, jako rozwiązaniu awaryjnym, trudno będzie ci wykonać to samo połączenie między źródłami. Chyba że nie zależy ci na bezpieczeństwie, oczywiście.
Oznacza to, że trudno jest mieć jedną zunifikowaną architekturę, która działa dla połączeń natywnych i obcych, chyba że jesteś przygotowany na włożenie sporo pracy lub skorzystanie z frameworka, który dobrze to zrobił. W idealnej architekturze nie zauważyłbyś, czy połączenia były natywne, czy nie; Twoje ustawienia bezpieczeństwa będą działać w obu przypadkach; Twoje ustawienia klastrowania nadal będą działać; twoje planowanie zdolności nadal by się utrzymało; i tak dalej.
Nie jest to tak proste, jak otwarcie strumienia HTTP i zatrzymanie się podczas przepływu danych przez minuty, godziny lub dłużej. Różni klienci zachowują się inaczej i musisz sobie z tym poradzić. Na przykład niektórzy klienci będą buforować dane i nie udostępniać ich do aplikacji, dopóki nie zostanie osiągnięty pewien próg. Co gorsza, niektórzy nie przekazują danych do aplikacji, dopóki połączenie nie zostanie zamknięte.
Więc jeśli wysyłasz wiele wiadomości do klienta, możliwe jest, że aplikacja kliencka nie otrzyma danych, dopóki na przykład nie otrzyma danych o wartości 50 wiadomości. To nie jest zbyt w czasie rzeczywistym.
Chociaż przesyłanie strumieniowe HTTP może być realną alternatywą, gdy protokół WebSocket nie jest dostępny, nie jest to panaceum. Wymaga dobrego zrozumienia, aby działać w sposób niezawodny na pustkowiach sieci w rzeczywistych warunkach.
Jest jeszcze jedna rzecz, o której nikt jeszcze nie wspomniał, więc poruszę to.
Protokół WebSocket został zaprojektowany jako warstwa transportowa dla protokołów wyższego poziomu. Chociaż możesz wysyłać wiadomości JSON lub inne rzeczy bezpośrednio przez połączenie WebSocket, może również przenosić standardowe lub niestandardowe protokoły.
Na przykład możesz zrobić AMQP lub XMPP przez WebSocket, tak jak ludzie już to zrobili. Tak więc klient może odbierać komunikaty od brokera AMQP, tak jakby był bezpośrednio połączony z samym brokerem (aw niektórych przypadkach tak jest).
Lub jeśli masz istniejący serwer z jakimś niestandardowym protokołem, możesz przetransportować go przez WebSocket, rozszerzając w ten sposób ten serwer zaplecza na Internet. Często istniejąca aplikacja, która została zablokowana w przedsiębiorstwie, może rozszerzyć swój zasięg za pomocą WebSocket, bez konieczności zmiany jakiejkolwiek infrastruktury zaplecza.
(Oczywiście chciałbyś móc to wszystko zrobić bezpiecznie, więc skontaktuj się z dostawcą lub dostawcą WebSocket).
Niektórzy określają WebSocket jako TCP dla sieci Web. Ponieważ tak jak TCP transportuje protokoły wyższego poziomu, tak samo jest z WebSocket, ale w sposób zgodny z infrastrukturą sieci Web.
Więc podczas gdy wysyłanie wiadomości JSON (lub cokolwiek innego) bezpośrednio przez WebSocket jest zawsze możliwe, należy również wziąć pod uwagę istniejące protokoły. Ponieważ w przypadku wielu rzeczy, które chcesz zrobić, prawdopodobnie został już wymyślony protokół, aby to zrobić.
To było świetne pytanie, a wszystkie odpowiedzi były bardzo pouczające!
źródło
(StackOverflow ogranicza rozmiar odpowiedzi na komentarze, więc musiałem odpowiedzieć tutaj, a nie w tekście).
Trafne spostrzeżenie. Aby to zrozumieć, pomyśl o tradycyjnym scenariuszu HTTP ... Wyobraź sobie, że przeglądarka otworzyła stronę internetową, więc żąda , powiedzmy, http://example.com . Serwer odpowiada za pomocą protokołu HTTP zawierającego kod HTML strony. Wtedy przeglądarka widzi, że na stronie są zasoby, więc zaczyna żądać plików CSS, plików JavaScript i oczywiście obrazów. Wszystkie są plikami statycznymi, które będą takie same dla wszystkich żądających ich klientów.
Niektóre serwery proxy będą buforować zasoby statyczne, aby kolejne żądania od innych klientów mogły pobierać te zasoby statyczne z serwera proxy, zamiast konieczności powrotu do centralnego serwera internetowego, aby je uzyskać. To jest buforowanie i jest to świetna strategia odciążania żądań i przetwarzania z usług centralnych.
Tak więc klient nr 1 żąda , powiedzmy, http://example.com/images/logo.gif . Żądanie to przechodzi przez proxy aż do centralnego serwera WWW, który wyświetla logo.gif. Gdy logo.gif przechodzi przez proxy, serwer proxy zapisze ten obraz i skojarzy go z adresem http://example.com/images/logo.gif .
Gdy pojawia się klient nr 2 i żąda również http://example.com/images/logo.gif , serwer proxy może zwrócić obraz i nie jest wymagana żadna komunikacja z powrotem do serwera WWW w centrum. Daje to szybszą reakcję użytkownikowi końcowemu, co zawsze jest świetne, ale oznacza również, że środek jest mniej obciążony. Może to przełożyć się na niższe koszty sprzętu, niższe koszty sieci itp. Więc to dobrze.
Problem pojawia się, gdy logo.gif jest aktualizowane na serwerze WWW. Serwer proxy będzie nadal obsługiwał stary obraz, nie wiedząc, że istnieje nowy obraz. Prowadzi to do całej sprawy związanej z wygaśnięciem, tak że proxy będzie buforować obraz tylko przez krótki czas, zanim "wygaśnie", a następne żądanie przechodzi przez proxy do serwera WWW, który następnie odświeża pamięć podręczną proxy. Istnieją również bardziej zaawansowane rozwiązania, w których serwer centralny może wypychać do znanych pamięci podręcznych i tak dalej, a sprawy mogą stać się dość wyrafinowane.
Jak to się ma do twojego pytania?
Zapytałeś o przesyłanie strumieniowe HTTP, gdzie serwer przesyła strumieniowo HTTP do klienta. Jednak przesyłanie strumieniowe HTTP jest takie samo jak zwykły HTTP, z wyjątkiem tego, że nie przestajesz wysyłać danych. Jeśli serwer sieciowy obsługuje obraz, wysyła HTTP do klienta, który ostatecznie się kończy: wysłałeś cały obraz. A jeśli chcesz wysłać dane, to jest dokładnie to samo, ale serwer po prostu wysyła przez naprawdę długi czas (jak na przykład gigantyczny obraz) lub nawet nigdy się nie kończy.
Z punktu widzenia proxy nie może odróżnić HTTP dla statycznego zasobu, takiego jak obraz, od danych z przesyłania strumieniowego HTTP. W obu przypadkach klient wysłał żądanie do serwera. Pełnomocnik zapamiętał to żądanie, a także odpowiedź. Następnym razem, gdy pojawi się to żądanie, serwer proxy podaje tę samą odpowiedź.
Więc jeśli twój klient zażądał, powiedzmy, ceny akcji i otrzymał odpowiedź, następny klient może wysłać to samo żądanie i uzyskać dane z pamięci podręcznej. Prawdopodobnie nie to, czego chcesz! Jeśli chcesz uzyskać ceny akcji, chcesz otrzymywać najnowsze dane, prawda?
Więc to jest problem.
To prawda, istnieją sztuczki i obejścia, które pozwalają poradzić sobie z takimi problemami. Oczywiście możesz sprawić, by przesyłanie strumieniowe HTTP działało, ponieważ jest obecnie używane. To wszystko jest przejrzyste dla użytkownika końcowego, ale ludzie, którzy opracowują i utrzymują te architektury, muszą przeskoczyć przez przeszkody i zapłacić cenę. Powoduje to nadmiernie skomplikowaną architekturę, co oznacza więcej konserwacji, więcej sprzętu, większą złożoność i większe koszty. Oznacza to również, że programiści często muszą dbać o coś, czego nie powinni, kiedy powinni po prostu skupić się na aplikacji, GUI i logice biznesowej - nie powinni martwić się o podstawową komunikację.
źródło
HTTP ogranicza liczbę połączeń, które klient może mieć z serwerem do 2 (chociaż można to złagodzić za pomocą subdomen), a IE jest znane z tego, że chętnie wymusza to. Firefox i Chrome pozwalają na więcej (chociaż nie pamiętam z czubka głowy dokładnie, ile). To może nie wydawać się dużym problemem, ale jeśli używasz stale jednego połączenia do aktualizacji w czasie rzeczywistym, wszystkie inne żądania muszą przepływać przez drugie połączenie HTTP. Jest też kwestia większej liczby otwartych połączeń od klientów, co powoduje większe obciążenie serwera.
WebSockets są protokołami opartymi na TCP i jako takie nie cierpią z powodu tego limitu połączeń na poziomie HTTP (ale oczywiście obsługa przeglądarek nie jest jednolita).
źródło