A lecke végére el tudod magyarázni az SSE működését, az újracsatlakozás és a Last-Event-ID szerepét, a hitelesítés és az infrastruktúra korlátait, és meg tudod különböztetni az SSE-t az általános HTTP streamingtől.
Miért kell?
A long polling minden válasz után új HTTP-cserét kér. Ha a szerver ugyanazon a nyitott válaszon sok üzenetet küldhet, kisebb a fejlécköltség és a késleltetés. Sok állapotfigyelő felületnek elég, ha az adat csak a szervertől a kliens felé áramlik.
Mi az SSE?
Az SSE HTTP-alapú szöveges eseményfolyam: a szerver egyetlen HTTP-válaszban több eseményt küld. A WHATWG HTML Standard szerint a formátum MIME-típusa text/event-stream, UTF-8 kódolású, az események üres sorral zárulnak, a mezők: event (típus), data (adat), id (az utolsó esemény azonosítója), retry (újracsatlakozási idő ezredmásodpercben). A kettősponttal kezdődő sor megjegyzés, amelyet a kliens figyelmen kívül hagy; a szabvány szerint egyes régi proxyk rövid idő után elvágják a kapcsolatot, ezért a szerző körülbelül 15 másodpercenként küldhet ilyen megjegyzést életjelként.
A böngészőben az EventSource API fogadja. Az MDN szerint a kapcsolat egyirányú: a kliens nem küldhet eseményt a szervernek, ezért a kliens műveletei külön csatornán, például fetch() kéréssel mennek.
Újracsatlakozás és Last-Event-ID
Az EventSource a kapcsolat megszakadása után alapértelmezésben újra csatlakozik; a szerver a retry mezővel adhat várakozási időt. Az újracsatlakozáskor a böngésző a Last-Event-ID fejlécben küldi az utoljára kapott eseményazonosítót. A szabvány szerint a 204 No Content válasz leállítja az újracsatlakozást, minden más nem-200 státusz vagy hibás Content-Type a kapcsolat végleges meghiúsulását jelenti, és a kliens nem próbálkozik újra.
Az automatikus újracsatlakozás nem garantálja a kimaradt események megérkezését. A szervernek meg kell őriznie az eseményeket (vagy más helyreállítási módot kell adnia) ahhoz, hogy a Last-Event-ID alapján folytatni lehessen; ha a régi pozíciót nem tudja kiszolgálni, a kliensnek friss pillanatképet (snapshot) kell kérnie.
Hitelesítés és infrastruktúra
Az EventSource konstruktora a szabvány szerint csak egy URL-t és a withCredentials opciót fogadja, tetszőleges kérésfejlécet nem lehet megadni. Cookie-alapú hitelesítésnél a hitelesítést, a credential-kezelést és a cross-origin szabályokat össze kell hangolni. Hosszú életű érzékeny tokent az URL-be írni rossz választás, mert a cím naplókba kerülhet.
A közbenső proxy pufferelése késleltetheti az eseményeket (az RFC 6202 általánosan is megjegyzi, hogy a streaminget a teljes választ pufferelő közbenső komponensek megakadályozhatják). Az MDN szerint HTTP/1.1 alatt böngészőnként és domainenként nagyon alacsony (6) a nyitott kapcsolatok száma, amely a lapok között közös; HTTP/2 esetén a párhuzamos streamek száma egyeztethető, az alapértelmezés 100.
Általános HTTP streaming
Az RFC 6202 szerint a HTTP streaming esetén a szerver nem fejezi be a választ, és adatot küld rajta, amikor van. A választeste a fetch API-val is olvasható darabonként, tetszőleges formátumban (például soronként tagolt JSON, NDJSON). Ilyenkor az alkalmazásnak saját elemzője van, és maga tervezi az üzenethatárt, az újracsatlakozást és a folytatást. Mivel a közbenső komponensek a darabolást átalakíthatják, az üzenethatárt az alkalmazás szintjén kell jelölni, nem a HTTP-darabolásra támaszkodva. Egy beérkező bájtdarab nem feltétlenül egy teljes üzenet, ezért az elemzőnek maradék puffert kell tartania és korlátoznia a méretet.
Jellemzők
Szempont
SSE / HTTP streaming
Irány
Egyirányú: szerver → kliens
Kezdeményező
A kapcsolatot a kliens nyitja; az eseményeket a szerver küldi
Kapcsolat tartóssága
Tartósan nyitott HTTP-válasz
Késleltetés
Alacsony: az esemény azonnal mehet
Terhelés
Nyitott kapcsolat per kliens; nincs ismételt fejlécköltség
Hibatűrés
Automatikus újracsatlakozás; kimaradt eseményekhez megőrzés vagy pillanatkép kell
Mikor jó?
Állapotfigyelés, értesítési folyam, élő felület csak szerver felől érkező adatra
Mikor nem?
Sűrű kétirányú üzenetváltás; speciális fejléces hitelesítés; bináris adat (SSE szöveges)
Gyakori tévhitek
Állítás
Pontosítás
„Az SSE kétirányú.”
Szerver → kliens; a kliens külön kéréssel küld.
„Az automatikus újracsatlakozás kihagyásmentes.”
A szerver megőrzése nélkül lemaradás keletkezhet.
„Az SSE-nek bármilyen fejléc beállítható.”
A konstruktor nem fogad fejlécet.
„Az SSE mindig valós idejűbb, mint a polling.”
Alacsonyabb késleltetést ad, de proxy pufferelhet.
Röviden
Az SSE egyirányú HTTP-eseményfolyam (text/event-stream), amelyet az EventSource fogad.
Az id és a Last-Event-ID folytatást tesz lehetővé, ha a szerver megőrzi az eseményeket.
Nincs egyedi kérésfejléc; az infrastruktúra (proxy, kapcsolatszám) korlátoz.
Az általános HTTP streamingnél a keretezést és a folytatást az alkalmazás oldja meg.
Ellenőrző kérdések
Mit kell a szervernek biztosítania a Last-Event-ID használatához?
Miért késhet az SSE egy proxy mögött?
Mit kell saját magunknak megoldani fetch-alapú NDJSON-streamnél?
Server-Sent Events és HTTP streaming
Célok
A lecke végére el tudod magyarázni az SSE működését, az újracsatlakozás és a
Last-Event-IDszerepét, a hitelesítés és az infrastruktúra korlátait, és meg tudod különböztetni az SSE-t az általános HTTP streamingtől.Miért kell?
A long polling minden válasz után új HTTP-cserét kér. Ha a szerver ugyanazon a nyitott válaszon sok üzenetet küldhet, kisebb a fejlécköltség és a késleltetés. Sok állapotfigyelő felületnek elég, ha az adat csak a szervertől a kliens felé áramlik.
Mi az SSE?
Az SSE HTTP-alapú szöveges eseményfolyam: a szerver egyetlen HTTP-válaszban több eseményt küld. A WHATWG HTML Standard szerint a formátum MIME-típusa
text/event-stream, UTF-8 kódolású, az események üres sorral zárulnak, a mezők:event(típus),data(adat),id(az utolsó esemény azonosítója),retry(újracsatlakozási idő ezredmásodpercben). A kettősponttal kezdődő sor megjegyzés, amelyet a kliens figyelmen kívül hagy; a szabvány szerint egyes régi proxyk rövid idő után elvágják a kapcsolatot, ezért a szerző körülbelül 15 másodpercenként küldhet ilyen megjegyzést életjelként.A böngészőben az
EventSourceAPI fogadja. Az MDN szerint a kapcsolat egyirányú: a kliens nem küldhet eseményt a szervernek, ezért a kliens műveletei külön csatornán, példáulfetch()kéréssel mennek.Újracsatlakozás és
Last-Event-IDAz
EventSourcea kapcsolat megszakadása után alapértelmezésben újra csatlakozik; a szerver aretrymezővel adhat várakozási időt. Az újracsatlakozáskor a böngésző aLast-Event-IDfejlécben küldi az utoljára kapott eseményazonosítót. A szabvány szerint a204 No Contentválasz leállítja az újracsatlakozást, minden más nem-200 státusz vagy hibásContent-Typea kapcsolat végleges meghiúsulását jelenti, és a kliens nem próbálkozik újra.Az automatikus újracsatlakozás nem garantálja a kimaradt események megérkezését. A szervernek meg kell őriznie az eseményeket (vagy más helyreállítási módot kell adnia) ahhoz, hogy a
Last-Event-IDalapján folytatni lehessen; ha a régi pozíciót nem tudja kiszolgálni, a kliensnek friss pillanatképet (snapshot) kell kérnie.Hitelesítés és infrastruktúra
Az
EventSourcekonstruktora a szabvány szerint csak egy URL-t és awithCredentialsopciót fogadja, tetszőleges kérésfejlécet nem lehet megadni. Cookie-alapú hitelesítésnél a hitelesítést, a credential-kezelést és a cross-origin szabályokat össze kell hangolni. Hosszú életű érzékeny tokent az URL-be írni rossz választás, mert a cím naplókba kerülhet.A közbenső proxy pufferelése késleltetheti az eseményeket (az RFC 6202 általánosan is megjegyzi, hogy a streaminget a teljes választ pufferelő közbenső komponensek megakadályozhatják). Az MDN szerint HTTP/1.1 alatt böngészőnként és domainenként nagyon alacsony (6) a nyitott kapcsolatok száma, amely a lapok között közös; HTTP/2 esetén a párhuzamos streamek száma egyeztethető, az alapértelmezés 100.
Általános HTTP streaming
Az RFC 6202 szerint a HTTP streaming esetén a szerver nem fejezi be a választ, és adatot küld rajta, amikor van. A választeste a
fetchAPI-val is olvasható darabonként, tetszőleges formátumban (például soronként tagolt JSON, NDJSON). Ilyenkor az alkalmazásnak saját elemzője van, és maga tervezi az üzenethatárt, az újracsatlakozást és a folytatást. Mivel a közbenső komponensek a darabolást átalakíthatják, az üzenethatárt az alkalmazás szintjén kell jelölni, nem a HTTP-darabolásra támaszkodva. Egy beérkező bájtdarab nem feltétlenül egy teljes üzenet, ezért az elemzőnek maradék puffert kell tartania és korlátoznia a méretet.Jellemzők
Gyakori tévhitek
Röviden
text/event-stream), amelyet azEventSourcefogad.idés aLast-Event-IDfolytatást tesz lehetővé, ha a szerver megőrzi az eseményeket.Ellenőrző kérdések
Last-Event-IDhasználatához?fetch-alapú NDJSON-streamnél?Források
EventSource, újracsatlakozás.