Szerver által küldött események tavasszal
1. Áttekintés
Ebben az oktatóanyagban megnézzük, hogyan tudjuk megvalósítani a Server-Sent-Events alapú API-kat a Spring alkalmazással.
Egyszerűen fogalmazva: a Server-Sent-Events vagy röviden az SSE egy HTTP szabvány, amely lehetővé teszi egy webalkalmazás számára, hogy egyirányú eseményfolyamot kezeljen, és frissítéseket fogadjon, amikor a szerver adatokat bocsát ki.
A 4.2-es tavaszi verzió már támogatta, de az 5-ös tavasztól kezdve már van egy idiomatikusabb és kényelmesebb módszer a kezelésére.
2. SSE az Spring 5 Webflux segítségével
Elérni ezt, használhatunk olyan megvalósításokat, mint a Fényáram osztály által biztosított Reaktor könyvtár, vagy potenciálisan a ServerSentEvent entitás, amely kontrollt ad számunkra az események metaadatai felett.
2.1. Stream Események használata Fényáram
Fényáram egy eseményfolyam reaktív ábrázolása - a megadott kérés vagy válaszmédia típusától függően másképp kezelik.
SSE streaming végpont létrehozásához be kell tartanunk a W3C specifikációit, és annak MIME típusát kell jelölnünk szöveg / eseményfolyam:
@GetMapping (path = "/ stream-flux", = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux streamFlux () {return Flux.interval (Duration.ofSeconds (1)) .map (szekvencia -> "Flux -" + LocalTime.now () .toString ()); }
A intervallum módszer létrehozza a Fényáram hogy kibocsát hosszú értékeket növekményesen. Ezután feltérképezzük ezeket az értékeket a kívánt kimenetre.
Indítsuk el az alkalmazást, és próbáljuk ki a végpont böngészésével.
Meglátjuk, hogyan reagál a böngésző azokra az eseményekre, amelyeket a szerver másodpercről másodpercre tol. További információ a Fényáram és a Reaktor magja, megnézhetjük ezt a bejegyzést.
2.2. A ServerSentEvent Elem
Most becsomagoljuk a kimenetünket Húr ba be ServerSentSevent objektumot, és vizsgálja meg ennek előnyeit:
@GetMapping ("/ stream-sse") nyilvános Flux streamEvents () {return Flux.interval (Duration.ofSeconds (1)) .map (szekvencia -> ServerSentEvent. builder () .id (String.valueOf (szekvencia)) .event ("periodic-event") .data (" SSE - "+ LocalTime.now (). ToString ()) .build ()); }
Ahogy tudjuk értékelni, van néhány előnye a ServerSentEvent entitás:
- tudjuk kezelni az események metaadatait, amelyekre valós esetben szükségünk lenne
- figyelmen kívül hagyhatjukszöveg / eseményfolyam”Médiatípus-nyilatkozat
Ebben az esetben egy id, an esemény neve, és ami a legfontosabb, a tényleges adat az esemény.
Azt is felvehettük volna a Hozzászólások attribútum, és a próbálja újra érték, amely meghatározza az újracsatlakozási időt, amelyet az esemény elküldéséhez használni kell.
2.3. A kiszolgáló által küldött események fogyasztása egy webkliens segítségével
Most fogyasszuk el eseményfolyamunkat a-val Web Ügyfél.:
public void consumeServerSentEvent () {WebClient ügyfél = WebClient.create ("// localhost: 8080 / sse-server"); ParameterizedTypeReference type = new ParameterizedTypeReference() {}; Fényáram eventStream = client.get () .uri ("/ stream-sse") .retrieve () .bodyToFlux (type); eventStream.subscribe (content -> logger.info ("Idő: {} - esemény: név [{}], id [{}], tartalom [{}]", LocalTime.now (), content.event (), content.id (), content.data ()), hiba -> logger.error ("Hiba az SSE fogadásakor: {}", hiba), () -> logger.info ("Befejezve !!!")); }
A Iratkozz fel A módszer lehetővé teszi számunkra, hogy jelezzük, hogyan tovább haladunk, ha sikeresen fogadunk egy eseményt, amikor hiba lép fel, és amikor a streaming befejeződik.
Példánkban a visszahoz módszer, amely a válasz testének megszerzésének egyszerű és egyértelmű módja.
Ez a módszer automatikusan dob a WebClientResponseException ha 4xx vagy 5xx választ kapunk, hacsak nem kezeljük a forgatókönyveket egy onStatus nyilatkozat.
Másrészt felhasználhattuk volna a csere módszer is, amely hozzáférést biztosít a ClientResponse és a hibás válaszok esetén sem jelez hibát.
Figyelembe kell vennünk, hogy megkerülhetjük a ServerSentEvent burkoló, ha nincs szükségünk az esemény metaadataira.
3. SSE Streaming tavasszal MVC
Mint mondtuk, az SSE specifikációt a 4.2 tavasz óta támogatták, amikor a SseEmitter osztály került bevezetésre.
Egyszerű fogalmakkal definiálunk egy ExecutorService, egy szál, ahol a SseEmitter meg fogja dolgozni az adatokat, és visszaküldi az emitter példányt, a kapcsolatot így nyitva tartva:
@GetMapping ("/ stream-sse-mvc") nyilvános SseEmitter streamSseMvc () {SseEmitter emitter = new SseEmitter (); ExecutorService sseMvcExecutor = Executors.newSingleThreadExecutor (); sseMvcExecutor.execute (() -> {try {for (int i = 0; true; i ++) {SseEventBuilder esemény = SseEmitter.event () .data ("SSE MVC -" + LocalTime.now (). toString ()) .id (String.valueOf (i)) .name ("sse esemény - mvc"); emitter.send (esemény); Thread.sleep (1000);}} catch (Kivétel ex) {emitter.completeWithError (ex); }}); visszatérő kibocsátó; }
Mindig győződjön meg arról, hogy a megfelelőt választotta ExecutorService a felhasználási eset forgatókönyvéhez.
Megtudhatunk többet az SSE-ről a tavaszi MVC-ben, és más érdekes példákat is megnézhetünk az érdekes oktatóanyag elolvasásával.
4. A szerver által küldött események megértése
Most, hogy tudjuk, hogyan kell megvalósítani az SSE végpontokat, próbáljunk meg egy kicsit mélyebbre menni néhány mögöttes fogalom megértésével.
Az SSE a legtöbb böngésző által elfogadott specifikáció, amely bármikor egyirányú streaminget engedélyez.
Az „események” csak az UTF-8 kódolású szöveges adatfolyamok, amelyek a specifikáció által meghatározott formátumot követik.
Ez a formátum kulcsérték-elemek (id, újrapróbálkozás, adatok és esemény, amely a nevet jelöli) sorokból áll, amelyeket sortörések választanak el egymástól.
A megjegyzéseket is támogatjuk.
A specifikáció semmilyen módon nem korlátozza az adat hasznos formátumát; használhatunk egy egyszerű Húr vagy egy összetettebb JSON vagy XML struktúra.
Egy utolsó szempont, amelyet figyelembe kell vennünk, az SSE streaming és a WebSockets.
Míg WebSockets teljes duplex (kétirányú) kommunikációt kínál a szerver és az ügyfél között, míg az SSE egyirányú kommunikációt használ.
Is, WebSockets nem HTTP protokoll, és az SSE-vel ellentétben nem kínál hibakezelési szabványokat.
5. Következtetés
Összefoglalva, ebben a cikkben megismertük az SSE streaming fő koncepcióit, ami kétségtelenül nagyszerű erőforrás, amely lehetővé teszi számunkra a következő generációs rendszerek létrehozását.
Most kiváló helyzetben vagyunk ahhoz, hogy megértsük, mi történik a motorháztető alatt, amikor ezt a protokollt használjuk.
Továbbá kiegészítettük az elméletet néhány egyszerű példával, amelyek megtalálhatók a Github-tárunkban.