WebSockets
Komunikacja pełnodupleksowa przez pojedyncze połączenie TCP dla aplikacji webowych.
Poza Modelem Żądanie-Odpowiedź: Potrzeba Komunikacji w Czasie Rzeczywistym
Przez lata sieć World Wide Web działała niemal wyłącznie w oparciu o model żądanie-odpowiedź protokołu HTTP. Klient (Twoja przeglądarka) wysyłał żądanie do serwera, a serwer odsyłał odpowiedź. Ta komunikacja była zawsze inicjowana przez klienta. Do przeglądania statycznych stron internetowych było to w zupełności wystarczające. Jednak w miarę ewolucji sieci w platformę dla dynamicznych, interaktywnych aplikacji, ten jednokierunkowy, sterowany przez klienta model zaczął wykazywać swoje ograniczenia.
Rozważmy aplikacje wymagające aktualizacji w czasie rzeczywistym: aplikację czatu na żywo, panel giełdowy pokazujący zmieniające się ceny, wieloosobową grę online czy edytor dokumentów do współpracy, taki jak Dokumenty Google. W świecie HTTP/1.1 osiągnięcie tego było trudne i nieefektywne. Deweloperzy uciekali się do różnych technik, znanych jako , aby symulować komunikację w czasie rzeczywistym:
- Krótkie Odpytywanie (Short Polling):Klient wielokrotnie wysyła żądania do serwera w stałych odstępach czasu (np. co 2 sekundy), pytając: "Czy masz coś nowego dla mnie?". Generuje to ogromny ruch sieciowy, ponieważ większość odpowiedzi jest pusta, i wprowadza zauważalne opóźnienie.
- Długie Odpytywanie (Long Polling, Comet): Ulepszenie, w którym klient wysyła żądanie, a serwer utrzymuje połączenie otwarte, dopóki nie będzie miał nowych danych do wysłania. Gdy dane zostaną wysłane, połączenie jest zamykane, a klient natychmiast otwiera nowe. Zmniejsza to liczbę pustych odpowiedzi, ale jest bardziej skomplikowane w implementacji i zużywa zasoby serwera.
Te obejścia były złożone, nieefektywne i dodawały znaczne opóźnienia. Sieć potrzebowała natywnego, standardowego sposobu, aby serwery mogły komunikować się z klientami bez wcześniejszej prośby. To doprowadziło do powstania protokołu WebSocket.
Czym jest WebSocket? Prawdziwa Dwukierunkowa Ulica
to technologia, która umożliwia dwukierunkową, interaktywną sesję komunikacyjną między przeglądarką użytkownika a serwerem. Zapewnia trwałe, niskoopoźnieniowe połączenie, które pozwala na wysyłanie danych w obu kierunkach w dowolnym momencie. Jest to znane jako .
W przeciwieństwie do tradycyjnego modelu HTTP, który otwiera połączenie, wysyła dane i je zamyka, WebSocket ustanawia jedno, długotrwałe połączenie TCP i utrzymuje je otwarte. Po jego ustanowieniu zarówno klient, jak i serwer mogą wysyłać do siebie wiadomości, kiedy tylko zajdzie taka potrzeba, bez narzutu związanego z tworzeniem nowych połączeń czy wysyłaniem powtarzalnych nagłówków HTTP przy każdej wiadomości. Tworzy to autentyczny, trwały kanał konwersacji, idealny dla aplikacji opierających się na wymianie danych w czasie rzeczywistym.
Uzgadnianie WebSocket: Ulepszanie Połączenia
Jednym z najsprytniejszych aspektów protokołu WebSocket jest sposób, w jaki się rozpoczyna. Został on zaprojektowany tak, aby był kompatybilny z istniejącą infrastrukturą sieciową, taką jak serwery HTTP i proxy. Nie wymaga specjalnego portu; inicjuje swoje życie przez standardowe połączenie HTTP/1.1. Ten początkowy proces jest znany jako uzgadnianie WebSocket (handshake).
Jak Działa Uzgadnianie
- Żądanie Klienta (Uaktualnienie HTTP):Klient (przeglądarka) inicjuje uzgadnianie, wysyłając standardowe żądanie HTTP GET do serwera. Jednak nie jest to zwykłe żądanie GET. Zawiera ono specjalne nagłówki, które sygnalizują zamiar klienta, aby "uaktualnić" połączenie z HTTP do WebSocket.
GET /czat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13Kluczowe nagłówki w tym żądaniu to:
Connection: UpgradeorazUpgrade: websocket: Te dwa nagłówki są oficjalnym sygnałem dla serwera, że klient chce zmienić protokół.Sec-WebSocket-Key: Klient wysyła losowo wygenerowaną wartość zakodowaną w Base64. Ten klucz nie służy do uwierzytelniania, ale jest częścią mechanizmu wyzwanie-odpowiedź, aby upewnić się, że serwer jest faktycznie świadomy WebSocket, a nie źle skonfigurowanym serwerem HTTP/1.1.
- Odpowiedź Serwera (Zmiana Protokołów): Serwer świadomy WebSocket, po otrzymaniu tego żądania o uaktualnienie, przetworzy je i odeśle specjalną odpowiedź HTTP. Jeśli serwer zgadza się na uaktualnienie, odpowie kodem statusu
101 Switching Protocols.HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Kluczowe elementy odpowiedzi to:
- Kod Statusu : Ten kod oficjalnie potwierdza, że serwer przełącza się z HTTP na protokół żądany w nagłówku `Upgrade`.
Sec-WebSocket-Accept: Aby udowodnić, że zrozumiał żądanie WebSocket, serwer bierzeSec-WebSocket-Keyklienta, łączy go z globalnie unikalnym magicznym ciągiem zdefiniowanym w specyfikacji protokołu, oblicza skrót SHA-1 wyniku, a następnie koduje go w Base64. Klient wykonuje te same obliczenia i weryfikuje, czy odpowiedź serwera się zgadza. To kończy uzgadnianie i zapobiega błędnemu odtworzeniu odpowiedzi przez buforujące serwery proxy.
Gdy to uzgadnianie zostanie pomyślnie zakończone, początkowe połączenie HTTP zostaje zastąpione. Podstawowe połączenie TCP zostaje przejęte przez protokół WebSocket. Od tego momentu klient i serwer mogą wymieniać dane za pomocą protokołu ramek WebSocket, nie wysyłając już nigdy nagłówków HTTP. Dwukierunkowa rozmowa została rozpoczęta.
Schematy URI WebSocket: `ws` i `wss`
Podobnie jak HTTP ma swój własny schemat URI (`http://`), WebSocket definiuje własne schematy do identyfikacji punktów końcowych WebSocket.
ws://(WebSocket)- Jest to schemat dla nieszyfrowanych połączeń WebSocket. Zazwyczaj działa on na porcie TCP 80, tak samo jak standardowy HTTP, co pomaga mu przechodzić przez zapory sieciowe. Ponieważ jest nieszyfrowany, jest podatny na podsłuch i powinien być używany tylko do danych niepoufnych w zaufanych sieciach.
wss://(WebSocket Secure)- Jest to bezpieczna wersja protokołu, analogiczna do HTTPS. Połączenie `wss` to połączenie WebSocket, które jest szyfrowane za pomocą TLS. Zazwyczaj działa na porcie TCP 443. Wszystkie nowoczesne aplikacje internetowe korzystające z WebSockets powinny używać schematu `wss`, aby zapewnić poufność i integralność wymienianych danych.
// Nieszyfrowane połączenie WebSocket
ws://czat.example.com/api
// Bezpieczne, szyfrowane połączenie WebSocket
wss://realtime.example.com/gieldaRamki Danych WebSocket: Protokół Konwersacji
Po uzgadnianiu wszystkie dane są wysyłane w jednostkach zwanych ramkami WebSocket. Jest to lekki protokół ramkowania, zaprojektowany w celu zminimalizowania narzutu. Każda ramka zaczyna się od małego nagłówka, po którym następuje ładunek zawierający dane aplikacji. Nagłówek zawiera metadane dotyczące ładunku.
- Bit FIN: Flaga wskazująca, czy jest to ostatnia ramka wiadomości. Pozwala to na fragmentację wiadomości na wiele ramek.
- Opcode: 4-bitowe pole, które wskazuje, jakiego rodzaju dane zawiera ładunek ramki. Popularne kody operacji to:
- `text`: Ładunek to dane tekstowe UTF-8.
- `binary`: Ładunek to surowe dane binarne.
- `close`: Specjalna ramka kontrolna do eleganckiego zamykania połączenia.
- `ping`/`pong`: Ramki kontrolne używane do sprawdzania połączenia (keep-alive), aby wykryć zerwane połączenie.
- Maskowanie: Ze względów bezpieczeństwa wszystkie ramki wysyłane od klienta do serwera muszą być maskowane 32-bitowym kluczem maskującym. Pomaga to zapobiegać atakom zatruwania pamięci podręcznej (cache poisoning) na pośredniczących serwerach proxy. Klucz maskujący jest zawarty w nagłówku ramki.
- Długość i dane ładunku: Nagłówek zawiera również długość ładunku, po której następują same dane ładunku.
Ten protokół ramkowania jest znacznie bardziej wydajny niż wysyłanie pełnych żądań i odpowiedzi HTTP. Narzut na wiadomość może wynosić zaledwie 2 bajty, w porównaniu do setek bajtów w przypadku nagłówków HTTP, co czyni WebSockets niezwykle dobrze przystosowanymi do przesyłania wiadomości o wysokiej częstotliwości.
Zastosowania i Aplikacje WebSocket
Dwukierunkowa natura WebSocket, działająca w czasie rzeczywistym, umożliwiła powstanie nowej klasy aplikacji internetowych, które wcześniej były niepraktyczne.
Aplikacje Czatowe
WebSockets są idealną technologią do tworzenia pokojów czatowych i aplikacji do przesyłania wiadomości. Kiedy jeden użytkownik wysyła wiadomość, serwer może natychmiast ją wypchnąć do wszystkich innych podłączonych klientów, bez potrzeby odpytywania o aktualizacje.
Wieloosobowe Gry Online
Gry wymagają komunikacji o bardzo niskim opóźnieniu do synchronizacji pozycji graczy, ich działań i stanu gry. WebSockets zapewniają szybki, dwukierunkowy kanał komunikacji niezbędny do płynnej rozgrywki bezpośrednio w przeglądarce.
Transmisje Danych Finansowych na Żywo
Notowania giełdowe, giełdy kryptowalut i pulpity finansowe muszą wyświetlać aktualizacje cen w momencie ich wystąpienia. Serwery mogą używać WebSockets do wypychania nowych notowań do tysięcy klientów jednocześnie.
Współpraca i Edycja w Czasie Rzeczywistym
Aplikacje takie jak Dokumenty Google czy edytory kodu do współpracy (np. VS Code Live Share) opierają się na WebSockets, aby natychmiast przesyłać naciśnięcia klawiszy i ruchy kursora od jednego użytkownika do wszystkich pozostałych uczestników sesji.
Powiadomienia w Czasie Rzeczywistym
Kiedy nadejdzie nowy e-mail, pojawi się wzmianka w mediach społecznościowych lub zakończy się proces na serwerze, serwer może użyć WebSocket, aby natychmiast powiadomić użytkownika w jego przeglądarce, zamiast czekać, aż użytkownik odświeży stronę.
Aktualizacje Sportowe na Żywo
Strony sportowe mogą wypychać na żywo wyniki, komentarze na bieżąco i statystyki do użytkowników w trakcie trwania akcji, zapewniając wciągające doświadczenie na drugim ekranie.
Podsumowanie: Nowoczesny Protokół dla Sieci Działającej w Czasie Rzeczywistym
Protokół WebSocket fundamentalnie zmienił sieć z systemu do pobierania dokumentów w pełnoprawną platformę dla interaktywnych aplikacji działających w czasie rzeczywistym. Zapewniając trwały, niskonakładowy, pełnodupleksowy kanał komunikacji przez pojedyncze połączenie TCP, elegancko rozwiązał nieefektywności starych modeli opartych na odpytywaniu przez klienta.
Dzięki sprytnemu mechanizmowi uzgadniania poprzez uaktualnienie HTTP, WebSocket zachowuje kompatybilność z istniejącą infrastrukturą sieciową, wprowadzając jednocześnie nowy paradygmat komunikacji inicjowanej przez serwer. Stał się niezbędnym narzędziem dla nowoczesnych deweloperów internetowych, napędzając bogate, współpracujące i natychmiastowe doświadczenia, których użytkownicy oczekują od dzisiejszych aplikacji.