Blog
Píšeme pre vás


WS, SSE, short-polling a long-polling
Rozmýšľal som, aký článok napísať a keďže to nie je dávno, čo som sa rozhodoval medzi týmito službami, rozhodol som sa priniesť krátky článok o každej z nich. Chcem upozorniť, že vo všetkých spomenutých prípadoch používam na strane servera jazyk PHP.
Začnem najskôr tým, ako prebieha komunikácia so serverom za bežných podmienok.
Klasické HTTP
Úplne základná požiadavka z prehliadača na server. Napríklad keď navštívite stránku a chcete vidieť iný obsah (napríklad inú podstránku), celý web sa znova načíta. Takto to vyzerá v praxi:
- Používateľ navštívi webovú stránku
- Server spracuje požiadavku, môže sťahovať údaje z databázy a podobne
- Server odošle výsledok do prehliadača
Ajax - Short polling
Ajax prebieha na pozadí pomocou JavaScriptu a môže tak dynamicky meniť obsah stránky. Short poling funguje tak, že sa JavaScript “opýta” niečo servera a po odpovedi a krátkom intervale pošle požiadavku znova. Napríklad ak sa nachádzate na stránke sociálnej siete a tam sa vám mení obsah bez toho, aby ste na niečo klikli, alebo sa presmerovali. Ako prebieha komunikácia:
- Používateľ navštívi webovú stránku (HTTP)
- Po načítaní sa spustí JavaScript, ktorý posiela požiadavky na server
- Prehliadač spracuje odpoveď a po krátkom intervale (napríklad po sekunde) sa spustí znova
Výhody:
- Jednoduché na naprogramovanie
- Nepožaduje VPS*
Nevýhody:
- Vďaka intervalom posiela veľa požiadaviek
- Vracajú sa odpovede aj keď sa reálne nič nezmenilo
- Pri komunikácií s databázou môže zbytočne zaťažovať server
Short polling si môžete otestovať na tejto stránke s ukážkou jednoduchého chatu.
Ajax - Long polling
Napriek podobnému názvu ako Short polling sa jedná o trocha inú službu. Funguje štýlom, že sa na server odošle požiadavka, server ju spracuje a vráti späť ale i s jedinečným údajom (napr. timestamp). Keď JavaScript spracuje odpoveď, znova odošle požiadavku, ale tentoraz aj s posledným obdržaným údajom. Server si kontroluje údaje a vypíše obsah až keď si “všimne” zmenu v údajoch a pre prehliadač to znamená, že musí čakať na odpoveď. Ako prebieha komunikácia:
- Používateľ navštívi webovú stránku (HTTP)
- Po načítaní sa spustí JavaScript, ktorý pošle požiadavku bez timestampu
- Server vráti obsah a tiež timestamp
- JavaScript spracuje obsah a znova zavolá sám seba, no na server už odošle aj posledný získaný timestamp
- Server skontroluje timestamp, ktorý obdržal, s novým timestamp-om
- Ak sa timestamp-y zhodujú, počká chvíľu, znova skontroluje a takto dookola až kým sa nezhodujú, vtedy prejde na b.
- Ak sa timestamp-y nezhodujú, vypíše obsah + odošle nový timestamp
- JavaScript sa znova zopakuje (bod 4)
Výhody:
- Posiela a spracováva požiadavky, len ak sa naozaj niečo zmení
- Nepožaduje VPS*
Nevýhody:
- Na strane servera sa často kontroluje rovnaký údaj (napríklad timestamp súborov)
- Kontroly zmien vhodné len pre súbory, nakoľko kontrolovať databázu by posielalo veľmi veľa požiadaviek (napríklad uložiť zmenu do súboru ale vypisovať údaje z databázy až potom)
- Pri zdieľaných hostingoch, kde nie je možné neobmedzene spúšťať PHP skripty (cez set_time_limit(0)) je potrebné navrhnúť aj obnovenie spojenia
Long polling si môžete otestovať na tejto stránke s ukážkou jednoduchého chatu.
Server Sent Events (SSE) / EventSource
V dnešnej dobe je podľa mňa zbytočné používať SSE, nakoľko je jednoduchšie nakódovať long-polling, ktorý bude fungovať takmer rovnako, alebo v prípade VPS* použiť oveľa lepšie a rýchlejšie WebSocket-y. Funguje štýlom, že sa pripojí na server a čaká na odpovede. Pokiaľ by sme použili rovnaký príklad ako pri long pollingu, zistíme, že cyklus na kontrolu zmeny súboru bude rovnaký, avšak kód samotný môže byť zbytočne veľký. Osobne som nenašiel lepšie využitie tejto služby oproti ostatným spomenutým. Funguje približne takto:
- Používateľ navštívi webovú stránku (HTTP)
- Po načítaní sa spustí JavaScript, ktorý sa pripojí na EventStream odosielaný serverom
- Prehliadač prijíma len informácie získané zo servera - nemusí sa znova pripájať
- Dáta prichádzajú ako eventy, pri chybe zo servera sa pokúsi o znovupripojenie
Výhody:
- Nepotrebuje posielať nové údaje na pripojenie a šetrí tak požiadavky
- Nepožaduje VPS*
Nevýhody:
- Nie je oveľa lepšie než long polling (subjektívny pohľad)
- Na strane servera sa často kontroluje rovnaký údaj (napríklad timestamp súborov)
- Kontroly zmien vhodné len pre súbory, nakoľko kontrolovať databázu by posielalo veľmi veľa požiadaviek (napríklad uložiť zmenu do súboru ale vypisovať údaje z databázy až potom)
- Nie je možné používať na rôznych doménach
SSE si môžete otestovať na tejto stránke s ukážkou reálnych cien známych značiek. Použil som externé demo, nakoľko nie všetky hostingy (vrátane nášho) podporujú EventStream v PHP.
WebSockets (WS)
Najlepšou voľbou zo spomínaných služieb sú “websockety”. Umožňujú priamu komunikáciu servera s prehliadačom, ale aj prehliadača so serverom. Služba funguje tým štýlom, že sa každé pripojenie “registruje”, na strane servera si môžeme uložiť jeho ID do pamäti a neskôr s ním vykonávať akcie. Využiť sa dá napríklad pri zmene, ktorú spraví iný používateľ, pošle sa event buď na všetkých, alebo len vybrané ID a im sa okamžite prejaví zmena. Ako prebieha komunikácia:
- Používateľ navštívi webovú stránku (HTTP)
- Po načítaní sa spustí JavaScript, ktorý vytvorí spojenie prehliadača a servera
- JavaScript pošle údaje kedy potrebuje
- Server pošle údaje kedy potrebuje
To je v skratke všetko - WebSocket-y nepotrebujú bežať v cykle, ani posielať požiadavky na server. Všetko sa odosiela a príjma presne vtedy keď to je treba.
Výhody:
- Veľmi rýchla technológia komunikácie
- Beží stále na pozadí a čaká len na spojenie
- Jeden používateľ môže inému (alebo aj všetkým) pomocou servera poslať správu v zlomku sekundy
- Nepotrebuje kontrolovať údaje (ako timestamp-y) a preto beží rýchlo aj server
Nevýhody:
- Požaduje sa VPS*
- Beží nezávisle a teda nebude možné používať sessions, v ktorých je napríklad uložený prihlásený používateľ
- Pri úprave kódu servera je potrebné reštartovať službu**
Pre PHP existuje viacero knižníc pre WebSocket-y, ktoré zabezpečia jednoduchú prácu so serverom. Osobne považuje Ratchet za najlepší.
* VPS - Virtual Private Server. Namiesto VPS môže byť aj klasický hosting, no je potrebné mať prístup ku konzole/SSH na zadávanie príkazov, alebo aspoň mať povolené používanie funkcie exec v PHP. Väčšina hostingov sú však zdieľané a takýto prístup nepovoľujú.
Ak si vezmeme príklad, že náš WebSocket server sa nachádza v súbore server.php, tak je potrebné do SSH/command line zadať tento príkaz:
php -q /cesta/k-suboru/server.php
Toto je potrebné, nakoľko server musí bežať nekonečne a v pozadí.
** reštartnúť službu - napríklad vo Windows v otvorenom command line stačí stlačiť kombináciu kláves CTRL+C, čo ukončí bežiaci proces a potom príkaz treba zadať znova. Na Linuxe to je rovnaké, avšak pri používaní SSH. Na Linuxe je však možné WebSockety nainštalovať a neskôr aj ovládať ako systémovú službu, no o tom bude až ďalší článok, kde konkrétnejšie uvediem aj príklad použitia WebSocket-ov s ukážkovými kódmi.
Verím, že vás článok zaujal a možno aj vysvetlil ako fungujú tieto asynchrónne služby pomocou JavaScriptu. Pokiaľ som na niečo zabudol, alebo nevysvetlil dobre, dajte nám vedieť v komentároch.
Zdroj obrazkov: https://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet
Uvodny obrazok: https://hpbn.co/websocket/