Komunikace v reálném čase díky Server-Sent Events a Web Sockets
AJAX nikdy nebyl jedinou možností, jak aktualizovat obsah webových stránek bez nutnosti jejich znovunačtení. Dalo se to provést ještě dynamickým vytvářením elementu script
s externím zdrojem (JSONP) nebo kořistěním dat z neviditelného a skrytě aktualizovaného iframe
či jiným podobným způsobem. AJAX byl ale nejpraktičtější. Jenže i AJAX má svou pověstnou Achillovu patu – tu představuje komunikace v reálném čase. AJAX ji neumí rozumným způsobem zajistit, přitom část tzv. RIAs (Rich Internet Applications) na ní je závislá. Význam těchto moderních aplikací nakonec vedl k realizaci sofistikovanějšího modelu komunikace mezi serverem a klienty.
Jak již bylo zmíněno v předchozím dílu, zaměřeném na řešení nedostatků AJAXu, proces výměny dat mezi webovou stránkou a serverem probíhá zpravidla podle HTTP protokolu. HTTP umožňuje pouze jednosměrnou komunikaci: klient inicializuje spojení se serverem a zašle požadavek, který server následně zpracuje, odešle odpověď a ukončí spojení. Pokud tedy klientská část aplikace očekávala data ze serveru, musel vždy vzniknout nejprve požadavek z její strany. Ten se buď v pravidelných intervalech opakoval (polling alias heartbeat), nebo server udržoval spojení do doby, než měl požadovaná data k dispozici (long-polling, streaming).
Konkrétních technik pro komunikaci v reálném čase byla vynalezena celá řada a dostaly souhrnné pojmenování – Comet; název vychází ze schématické představy serveru jako jádra komety s hustým a dlouhým ohonem vláken neukončených spojení. Nicméně starší techniky jsou dnes již, dá-li se to tak říct, překonané a ustupuje se i od AJAXu. W3C specifikovalo rovnou dvoje řešení pro zjednodušení a zefektivnění průběhu komunikace v reálném čase.
Server-Sent Events
Server-Sent Events nepředstavují komplexní řešení, jsou vlastně jen příspěvkem k ulehčení těžké práce chudáků programátorů klientských skriptů. V podstatě se jedná o implementací long-pollingu v prohlížeči. Díky tomu, že se prohlížeč sám stará o některé věci, především o základní roztřízení došlých dat nebo také o obnovu ukončeného spojení, může být kód skriptu úspornější a přehlednější.
Serverem zasílané informace musí mít zvláštní MIME typ – text/event-stream – a příslušný tvar:
event: update data: {"username": "Smoula", "emotion": "angry"} id: 3 : tohle už je událost message data: Tak kdy už mi sakra data: vrátíš ty prachy?
Každý řádek by měl začínat prefixem s dvojtečkou. Pokud začíná jenom dvojtečkou, tak se jedná o komentář. Úplně prázdný řádek znamená konec události. Výše uvedený kód představuje dvě události. Každá je brána zvlášť.
event: |
definuje typ události; výchozím typem události je message |
data: |
řetězcový literál bez uvozovek – může být sice rozdělen na více prefixovaných řádků, stále to však bude jediný řetězec |
id: |
ID události |
retry: |
počet milisekund, tuto dobu by měl prohlížeč vyčkat, než se pokusí obnovit spojení; obvykle prohlížeč vyčkává asi 3 sekundy |
Aplikace v prohlížeči přebírá servírovaná data následujícím způsobem:
var friends = { "Smoula": {"emotion": "happy", "age": 28}, "Gargamel": {"emotion": "happy", "age": 19} }; window.onload = function() { var source = new EventSource("chat.php"); source.addEventListener("message",function(e) { document.getElementById("zprava").textContent = e.data; },false); source.addEventListener("update",function(e) { var kamarad=JSON.parse(e.data); friends[kamarad.username].emotion = kamarad.emotion; },false); };
Konstruktor EventSource()
může mít dva argumenty: prvním je URL a tím druhým (nepovinným) v podobě logické hodnoty se povoluje režim CORS.
addEventListener() |
Metoda známá z DOM, zde je využita k registraci definovaných událostí |
close() |
uzavře spojení |
url |
URL serveru; pouze ke čtení |
withCredentials |
udává, zda je použit režim pro CORS; pouze ke čtení |
readyState |
stav připojení k serveru (hodnoty: 0 – probíhá navázání spojení, 1 – spojení otevřeno, 2 – spojení uzavřeno); pouze ke čtení |
Dále jsou objektu EventSource atributně přiřazeny ovladače událostí onopen
, onmessage
, onerror
. A to je z rozhraní EventSource
všechno, žádný mechanismus, který by umožňoval posílat data na server tu už není. Server-Sent Events se hodí v podstatě jen na zasílání notifikací.
Je také nutno poznamentat, že z hlediska serveru se jedná o klasický long-polling nebo streaming, pouze se změnil formát dat.
Web Sockets
Pojem socket znamená v programátorské terminologii komunikační spojení mezi dvěma koncovými uzly prostřednictvím IP. Socket tedy udržuje pomocí dvojice IP adres a portu stálý kanál pro spojení klienta se serverem. Takto mohou oba koncové body v reálném čase zasílat data simultánně přes jeden socket, což transportní protokol TCP umožňuje. Na bázi aplikační vrstvy však je nezbytné udělat změnu a místo tradičního protokolu HTTP použít protokol WS (Web Socket) nebo pro zabezpečené spojení WSS (Web Socket with SSL) místo HTTPS. HTTP je použit jen pro úvodní výměnu hlaviček, tzv. handshake.
Implementace aplikačního rozhraní WebSocket je v JavaScriptu ustavena jako objekt WebSocket
.
var params, mode; ... var socket = new WebSocket('ws://netgame.cz:210/updates'); socket.onopen = function() { this.send(params); }; socket.onmessage = function(e) { params = JSON.parse(e.data); } socket.onclose() { mode = 1; alert("Přepnuto do režimu single player"); }
Konstruktor WebSocket()
může mít dva argumenty: prvním je URL a tím druhým (nepovinným) subprotokol, případně pole subprotokolů.
url |
URL serveru; pouze ke čtení |
protocol |
vrací prázdný řetězec, nebo použitý subprotokol; pouze ke čtení |
readyState |
stav připojení k serveru (hodnoty: 0 – probíhá navázání spojení, 1 – spojení otevřeno, 2 – spojení uzavíráno, 3 – spojení uzavřeno); pouze ke čtení |
bufferedAmount |
počet bytů dat čekajících na odeslání; pouze ke čtení |
binaryType |
určuje, jak má skript interpretovat binární data; výchozí hodnotu blob , lze změnit na arraybuffer |
send() |
odešle data (řetězec, pole nebo soubor) |
close() |
uzavře spojení |
WebSocket
pracuje s událostmi open
, message
, close
a error
, viz příklad výše.
Ze srovnání představených technologií vychází jednoznačně vítězně Web Sockets: protokol pro obousměrnou komunikaci + jednoduché API, které zvládá vše, co je potřeba. A v neposlední řadě Web Sockets šetří systémové prostředky (paměť, CPU) serveru, které by jinak byly vynakládány na udržení procesu živého spojení.
Odkazy a zdroje
- Server-Sent Events – W3C Recommendation
- The WebSocket API – W3C Candidate Recommendation
- The WebSocket protocol – IETF Proposed Standard
- HTML 5 Web Sockets vs. Comet and Ajax – Dio Synodinos (2008)
- Stream Updates with Server-Sent Events – Eric Bidelman (2010)
- WebSockets vs Server-Sent Events vs Long-polling – Dmitry Sheiko (2012)
Celý seriál najdete pod štítkem: komunikace mezi stránkou a serverem
Mohlo by vás také zajímat
-
Netcat a Ncat
8. prosince 2022 -
Jak si vyzkoušet Apple Intelligence v EU
2. srpna 2024 -
Jak zabezpečit váš chytrý telefon před kybernetickými hrozbami
30. listopadu 2023 -
Windows App: Pracujte odkudkoliv, kdykoliv
3. listopadu 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024