Krzysztof Rychlicki-Kicior
Language: Polish
Dawno temu, gdy w kodzie HTML królowały znaczniki FONT i MARQUEE, a zamiast AJAX-a stosowano ukryte ramki, błyskawiczną i dwustronną komunikację z serwerem można było osiągnąć jedynie za pomocą specjalnych wtyczek - np. we wszelkiej maści czatach królowała wówczas Java i applety. Z upływem lat sytuacja poprawiła się, dzięki zastosowaniu AJAX-a czy long pollingu, jednak wciąż była daleka od ideału. Na szczęście, obecnie programiści są w znacznie lepszej sytuacji - dzięki WebSocketom bez żadnego problemu są w stanie zaimplementować komunikację w czasie rzeczywistym, niezbędną np. do gier online, aplikacji do komunikacji czy aplikacji finansowych.
W ramach tego wykładu słuchacze zapoznają się z różnymi koncepcjami stosowanymi w komunikacji pomiędzy przeglądarką a serwerem HTTP, z uwzględnieniem WebSocketów. Oprócz tego zostaną przedstawione mechanizmy obsługi WS od strony serwera, na przykładzie Node.js i Socket.IO. Różne rozwiązania zostaną poddane porównaniu pod kątem wydajności. Mimo licznych zalet, WebSockety niosą za sobą pewne problemy - zostaną one również poddane analizie.
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach webowych - Krzysztof Rychlicki-Kicior
1. Szybciej, niż Struś Pędziwiatr
WebSockets w aplikacjach webowych
Krzysztof Rychlicki-Kicior
Jack of all trades @
Ph.D. student & T.A. @ Politechnika Łódzka
2. Plan prezentacji
• Protokół HTTP i jego ograniczenia
• Ramki, Java, AJAX, czyli jak to dawniej bywało
• WebSockets – komunikacyjna magia teraz w Twojej
przeglądarce
• Struś Pędziwiatr czy Wile E. Coyote – porównanie
wydajności
3. HTTP
• Żądanie + odpowiedź = …i żyli długo i szczęśliwie…
• …ale czy aby na pewno?
• HTTP powstał jako protokół do obsługi powiązanych
ze sobą dokumentów hipertekstowych – obecnie
jest używany w znacznie szerszym kontekście
4. HTTP – problemy
• Jedno połączenie na jeden zasób – rozwiązane (keep
alive)
• Bezstanowość (brak sesji) – rozwiązane (sesje,
udostępniane przez popularne frameworki webowe)
• Jednostronność komunikacji – to klient decyduje o
komunikacji z serwerem – ?
• Wydajność – protokół HTTP wprowadza spory narzut,
który utrudnia komunikację w czasie rzeczywistym – ?
5. Powrót do przeszłości
• Przedstawione ograniczenia są znane od dawna i w
rozmaity sposób próbowano sobie z nimi radzić
• Rozwiązania można podzielić na dwie grupy:
natywne i wtyczki
• Do rozwiązań natywnych można zaliczyć iframe,
AJAX, rozwiązania typu long-polling
• Najpopularniejsze rozwiązania zewnętrzne opierały
się o applety Javy i aplikacje Flashowe
6. Ramki (iframe)
• Jedna z uniwersalnych metod
• Niewidoczna ramka (np. wymiary 0x0) wysyła
żądania cyklicznie lub na zasadzie tzw. forever
frame
7. AJAX
• Tradycyjnie AJAX jest używany do wykonywania
żądań "w tle"
• Dzięki zdarzeniu onreadystatechange, istnieje
możliwość przesyłania cząstkowych odpowiedzi,
podobnie jak w przypadku ramki
• Problem w tym podejściu (podobnie jak forever
frame) wynika z owego braku ograniczeń
8. Long polling
• Rozwiązanie stanowią techniki oparte o long-polling
• Żądanie jest utrzymywane dopóty, dopóki nie
zostaną przesłane dane, jednak z pewnym
czasowym ograniczeniem.
• W razie braku otrzymanych danych, klient ponawia
żądanie
9. Long polling – AJAX
• Nie jest to stricte nowa technika
• Sposób zastosowania AJAX-a zgodnie z założeniami
long pollingu
10. Long polling – JSONP
• AJAX nie może być powszechnie używany do
wywołań międzyserwerowych (cross-domain)
• Możliwość taką daje importowanie skryptów za
pomocą znacznika <script>:
<script src="http://serwer/uzytkownicy/1?callback=odpowiedz"
type="text/javascript"></script>
<script>
function odpowiedz(dane)
{
// skorzystaj z obiektu dane
}
</script>
11. Long polling – JSONP
• Serwer nie zwraca wyłącznie obiektu w formacie
JSON
• Konieczne jest "opakowanie" go w wywołanie
funkcji – w efekcie w kodzie strony jest importowany
następujące wywołanie:
odpowiedz({"ID":1, "Login":"jan12345"});
12. Rozwiązania zewnętrzne
• Java i applety – które królowały w latach 90. –
zapewniały wydajną komunikację za pomocą
gniazd TCP
• Konieczność posiadania Javy
• Dostępność dodatkowych portów
• Odrębna infrastruktura po stronie serwera
13. Rozwiązania zewnętrzne
• Pozostałe wady appletów:
o utrudniona komunikacja z resztą strony internetowej
o niespójny interfejs użytkownika
o certyfikaty, ostrzeżenia, etc…
14. Rozwiązania zewnętrzne
• Z nastaniem nowego wieku popularność zyskała
technologia Adobe Flash
• Zalety i wady podobne, jak w przypadku Javy
• Oprócz klasycznych gniazd TCP, Flash (a dokładnie
Flex) oferuje wsparcie dla wydajnych metod
integracji klientów i serwera (np. BlazeDS)
15. Nowe koncepcje
• Server-sent Events – serwer otrzymuje w pełni
funkcjonalne narzędzie do przesyłania
komunikatów do klientów
• SSE nie są obsługiwane w IE, a ponadto umożliwiają
one jedynie komunikację od serwera do klienta
• WebSockets – pozwalają na dwustronną
komunikację pomiędzy klientem, a serwerem, za
pomocą dedykowanego protokołu
16. WebSockets
• Dwukierunkowy kanał komunikacyjny, który
pozwala na przesyłanie danych z minimalnym
narzutem, w porównaniu do klasycznego protokołu
HTTP
• NIE jest to implementacja klasycznych gniazd TCP
ani UDP, mimo że zasada działania jest podobna
• Nie jest ograniczony tylko do przeglądarki: można
pisać aplikacje desktopowe z wykorzystaniem
zewnętrznych bibliotek, np. Jetty (w Javie)
17. WebSockets
Procedura nawiązania połączenia WebSockets:
1. Klient wysyła zwykłe żądanie HTTP pod adres URI
spełniający wymagania WebSockets:
2. Żądanie zawiera prośbę o wykonanie tzw.
Upgrade w celu rozpoczęcia komunikacji
dwukierunkowej w trybie full-duplex
3. Komunikacja dwukierunkowa jest prowadzona
niezależnie od innych żądań kierowanych do
serwera
ws://serwer.com/gra
18. WebSockets
• Połączenie WebSocket jest zrywane w momencie
przeładowania lub przejścia do innej strony
• Z tego względu, aplikacje intensywnie
wykorzystujące WS funkcjonują w obrębie jednej
strony
19. WebSockets
• Gniazda webowe pozwalają na transfer danych
tekstowych, jak i binarnych
• Podobnie jak w przypadku protokołu HTTP, tak i
WebSockety potrafią korzystać z protokołu SSL.
Zakładając wsparcie po stronie serwera, w kodzie
klienta wystarczy zastosować scheme wss.
20. WebSockets
• Po stronie serwera, WebSockety muszą być
zaimplementowane dodatkowo.
• Wsparcie dla WS jest obecne w licznych
technologiach server-side, takich jak Java EE 7,
ASP.NET czy Node.js
21. WebSockets
• Implementacja po stronie klienta jest trywialna:
var socket = new WebSocket("ws://localhost/czat");
socket.onmessage = function(evt) {
// korzystaj z evt.data
}
socket.send('Hello, World!’);
22. WebSockets
• Również po stronie serwera obsługa nie sprawia
zazwyczaj problemu:
@ServerEndpoint(value="/czat")
public class CzatEndpoint {
@OnMessage
public void handle(String msg, Session ses){
}
// pozostałe adnotacje: @OnOpen, @OnClose,
// @OnError
}
23. WebSockets
• W porównaniu do tradycyjnych gniazd sieciowych,
WebSockety oferują znacznie bardziej przejrzyste
API:
o otwarcie sesji
o zamknięcie sesji
o wysłanie komunikatu
o odebranie komunikatu
o obsługa błędów
24. Wydajność
• Jedną z kluczowych zalet WebSocketów jest ich
wydajność, zwłaszcza w przypadku przesyłania
dużej liczby małych komunikatów
• W takich sytuacjach narzut związany z
wykonywaniem żądań HTTP staje się ogromny
25. Wydajność
• Na potrzeby niniejszej prezentacji wykonałem
proste testy z wykorzystaniem technologii Node.JS i
biblioteki Socket.IO
• Socket.IO pozwala na stosowanie różnych
transportów przezroczyście dla programisty
• Obecnie, Socket.IO udostępnia WebSockety i XHR-
polling
26. Wydajność
• Scenariusz: 500 komunikatów przesyłanych
sekwencyjnie
• Testy były przeprowadzane lokalnie, aby
zlikwidować niepotrzebne opóźnienie
• Wyniki:
o WebSockets – 2542 ms
o XHR-polling – 12431 ms
27. Praktyczne zastosowania
• Narzędzia do komunikacji w czasie rzeczywistym
(czaty, narzędzia do pracy wspólnej – wirtualne
tablice, itd.)
• Gry
• Aplikacje finansowe