Realtime w przeglądarce: od pollingu do WebTransport
- data
- kategoria
- Backend
- także w
- Frontend · Networking
- czytanie
- 1 min / 274 słów
Klasyczny model webu jest prosty:
client -> request -> server
client <- response <- server
Klient inicjuje komunikację. Serwer odpowiada.
Problem zaczyna się wtedy, gdy stan zmienia się po stronie backendu po zakończeniu requestu.
t=0 GET /orders/42 -> processing
t=4 backend: processing -> completed
Skąd frontend ma wiedzieć o zmianie w t=4?
To jest punkt wyjścia tej serii.
Nie będziemy traktować „realtime” jako jednej technologii. Realtime jest wymaganiem dotyczącym maksymalnego akceptowalnego opóźnienia informacji, a nie nazwą protokołu.
realtime != WebSocket
Dla jednego systemu aktualizacja po 10 sekundach jest wystarczająco szybka. Dla innego 100 ms jest zbyt wolne.
Przejdziemy przez mechanizmy od najprostszego do najbardziej elastycznego:
Polling
|
v
Long Polling
|
v
HTTP Streaming
|
v
Server-Sent Events
|
v
WebSocket
|
v
WebTransport
Każdy kolejny wynika z konkretnego ograniczenia poprzedniego.
Polling ponawia requesty, nawet gdy nic się nie zmieniło. Long polling pozwala serwerowi opóźnić odpowiedź. HTTP streaming pozwala jednej odpowiedzi zawierać wiele fragmentów danych. SSE dodaje do takiego strumienia standardowy format zdarzeń i reconnect. WebSocket odchodzi od modelu request/response i daje trwały kanał full-duplex. WebTransport idzie dalej: wiele niezależnych streamów oraz datagramy nad HTTP/3.
Po drodze rozdzielimy też warstwy, które często są mieszane:
WebSocket
-> protocol + browser API
Socket.IO
-> higher-level realtime protocol/framework
GraphQL Subscription
-> application-level subscription semantics
WebRTC DataChannel
-> peer-to-peer communication
Socket.IO może używać WebSocketu, ale Socket.IO nie jest WebSocketem.
GraphQL Subscription może być dostarczana przez WebSocket albo inny transport, ale sama subskrypcja nie definiuje transportu.
WebRTC rozwiązuje jeszcze inny problem, ponieważ po zestawieniu połączenia dane mogą płynąć peer-to-peer zamiast frontend ↔ backend.
Seria skupia się na komunikacji klient-serwer. Nie będzie tutorialem do budowania chatu ani katalogiem bibliotek.
Interesują nas mechanizmy:
- kto inicjuje przepływ danych,
- jak długo żyje request lub connection,
- gdzie istnieje stan połączenia,
- jak wygląda framing danych,
- co dzieje się przy reconnect,
- jak mechanizm wpływa na load balancer i backend,
- gdzie pojawia się backpressure,
- co naprawdę oznacza „push”.
Na końcu wybór technologii powinien wynikać z modelu ruchu:
How fresh must data be?
|
v
Who sends data?
|
v
How often?
|
v
Do messages need ordering?
|
v
Can old messages be discarded?
|
v
What connection state can infrastructure support?
Dopiero potem wybieramy mechanizm.
Nie odwrotnie.