Reaktive WebSockets med fjeder 5

1. Oversigt

I denne artikel vil vi oprette et hurtigt eksempel ved hjælp af den nye Spring 5 WebSockets API sammen med reaktive funktioner leveret af Spring WebFlux.

WebSocket er en velkendt protokol, der muliggør fuld duplexkommunikation mellem klient og server, der generelt bruges i webapplikationer, hvor klienten og serveren har brug for at udveksle begivenheder med høj frekvens og med lav latenstid.

Spring Framework 5 har moderniseret WebSockets-understøttelse i rammen og tilføjer reaktive muligheder til denne kommunikationskanal.

Vi kan finde mere på Spring WebFlux her.

2. Maven-afhængigheder

Vi skal bruge afhængighed af spring-boot-starters til spring-boot-integration og spring-boot-starter-webflux, der i øjeblikket er tilgængelig på Spring Milestone Repository.

I dette eksempel bruger vi den senest tilgængelige version, 2.0.0.M7, men man skal altid få den nyeste version tilgængelig i Maven-arkivet:

 org.springframework.boot spring-boot-starter-integration org.springframework.boot spring-boot-starter-webflux 

3. WebSocket-konfiguration om foråret

Vores konfiguration er ret ligetil: Vi indsprøjter WebSocketHandler til at håndtere socket-sessionen i vores Spring WebSocket-applikation.

@Autowired privat WebSocketHandler webSocketHandler; 

Lad os desuden oprette en HandlerMapping bønne-kommenteret metode, der er ansvarlig for kortlægningen mellem anmodninger og handlerobjekter:

@Bean public HandlerMapping webSocketHandlerMapping () {Map map = new HashMap (); map.put ("/ event-emitter", webSocketHandler); SimpleUrlHandlerMapping handlerMapping = ny SimpleUrlHandlerMapping (); handlerMapping.setOrder (1); handlerMapping.setUrlMap (kort); returhåndtering Kortlægning; }

Den URL, vi kan oprette forbindelse til, er: ws: // localhost: / event-emitter.

4. Håndtering af WebSocket-meddelelser om foråret

Vores ReactiveWebSocketHandler klasse vil være ansvarlig for styring af WebSocket-sessionen på serversiden.

Det implementerer WebSocketHandler interface, så vi kan tilsidesætte håndtere metode, som vil blive brugt til at sende meddelelsen til WebSocket-klienten:

@Component public class ReactiveWebSocketHandler implementerer WebSocketHandler {// private felter ... @ Override offentligt monohåndtag (WebSocketSession webSocketSession) {return webSocketSession.send (intervalFlux .map (webSocketSession :: textMessage)). Og (webSocketSession.receive (). (WebSocketMessage :: getPayloadAsText) .log ()); }}

5. Oprettelse af en simpel reaktiv WebSocket-klient

Lad os nu oprette en Spring Reactive WebSocket-klient, der er i stand til at oprette forbindelse og udveksle oplysninger med vores WebSocket-server.

5.1. Maven afhængighed

For det første Maven afhængigheder.

 org.springframework.boot spring-boot-starter-webflux 

Her bruger vi den samme spring-boot-starter-webflux, der tidligere blev brugt til at opsætte vores reaktive WebSocket-serverapplikation.

5.2. WebSocket-klient

Lad os nu oprette ReactiveClientWebSocket klasse, der er ansvarlig for at starte kommunikationen med serveren:

public class ReactiveJavaClientWebSocket {public static void main (String [] args) throw InterruptedException {WebSocketClient client = new ReactorNettyWebSocketClient (); client.execute (URI.create ("ws: // localhost: 8080 / event-emitter"), session -> session.send (Mono.just (session.textMessage ("event-spring-reactive-client-websocket")) )) .thenMany (session.receive () .map (WebSocketMessage :: getPayloadAsText) .log ()) .then ()) .block (Duration.ofSeconds (10L)); }}

I koden ovenfor kan vi se, at vi bruger ReactorNettyWebSocketClient, som er WebSocketClient implementering til brug med Reactor Netty.

Derudover opretter klienten forbindelse til WebSocket-serveren via URL'en ws: // localhost: 8080 / event-emitter, oprettelse af en session, så snart den er forbundet til serveren.

Vi kan også se, at vi sender en besked til serveren (“event-spring-reactive-client-websocket“) Sammen med anmodningen om forbindelse.

Desuden er metoden sende påberåbes og forventer som parameter en variabel af typen Forlægger, som i vores tilfælde vores Forlægger er Mono og T er en simpel streng “event-me-from-reactive-java-client-websocket“.

Desuden er derefterMange (…) metode forventer en Strøm af typen Snor påberåbes. Det modtage() metode får strømmen af ​​indgående beskeder, som senere konverteres til strenge.

Endelig blev blok() metode tvinger klienten til at afbryde forbindelsen til serveren efter den givne tid (10 sekunder i vores eksempel).

5.3. Start af klienten

For at køre det skal du sørge for, at Reactive WebSocket Server er i gang. Start derefter ReactiveJavaClientWebSocket klasse, og vi kan se på sysout log de begivenheder, der udsendes:

[reaktor-http-nio-4] INFO reaktor.Flux.Map.1 - onNext ({"eventId": "6042b94f-fd02-47a1-911d-dacf97f12ba6", "eventDt": "2018-01-11T23: 29: 26.900 "})

Vi kan også se loggen fra vores Reactive WebSocket-server meddelelsen sendt af klienten under forbindelsesforsøget:

[reactor-http-nio-2] reactor.Flux.Map.1: onNext (event-me-from-reactive-java-client)

Vi kan også se meddelelsen om afbrudt forbindelse, når klienten har afsluttet sine anmodninger (i vores tilfælde efter de 10 sekunder):

[reaktor-http-nio-2] reaktor.Flux.Map.1: onComplete ()

6. Oprettelse af en browser WebSocket-klient

Lad os oprette en simpel HTML / Javascript-klient WebSocket til at forbruge vores reaktive WebSocket-serverapplikation.

 var clientWebSocket = ny WebSocket ("ws: // localhost: 8080 / event-emitter"); clientWebSocket.onopen = funktion () {console.log ("clientWebSocket.onopen", clientWebSocket); console.log ("clientWebSocket.readyState", "websocketstatus"); clientWebSocket.send ("begivenhed-mig-fra-browser"); } clientWebSocket.onclose = funktion (fejl) {console.log ("clientWebSocket.onclose", clientWebSocket, fejl); begivenheder ("Lukning af forbindelse"); } clientWebSocket.onerror = funktion (fejl) {console.log ("clientWebSocket.onerror", clientWebSocket, fejl); begivenheder ("Der opstod en fejl"); } clientWebSocket.onmessage = funktion (fejl) {console.log ("clientWebSocket.onmessage", clientWebSocket, fejl); begivenheder (error.data); } funktionshændelser (responsEvent) {document.querySelector (". events"). innerHTML + = responsEvent + "

"; }

Når WebSocket-serveren kører, åbner denne HTML-fil i en browser (f.eks. Chrome, Internet Explorer, Mozilla Firefox osv.), Skal vi se begivenhederne udskrives på skærmen med en forsinkelse på 1 sekund pr. Begivenhed som defineret i vores WebSocket-server.

{"eventId": "c25975de-6775-4b0b-b974-b396847878e6", "eventDt": "2018-01-11T23: 56: 09.780"} {"eventId": "ac74170b-1f71-49d3-8737-b3f9a8a352f9", "eventDt": "2018-01-11T23: 56: 09.781"} {"eventId": "40d8f305-f252-4c14-86d7-ed134d3e10c6", "eventDt": "2018-01-11T23: 56: 09.782"}

7. Konklusion

Her har vi præsenteret et eksempel på, hvordan man opretter en WebSocket-kommunikation mellem server og klient ved hjælp af Spring 5 Framework, implementering af de nye reaktive funktioner leveret af Spring Webflux.

Som altid kan det fulde eksempel findes i vores GitHub-lager.


$config[zx-auto] not found$config[zx-overlay] not found