Inleiding tot WebSockets met Spring

1. Overzicht

In dit artikel maken we een eenvoudige webtoepassing die berichtenuitwisseling implementeert met de nieuwe WebSocket-mogelijkheden geïntroduceerd met Spring Framework 4.0.

WebSockets is een bidirectioneel, volledig duplex, aanhoudende verbinding tussen een webbrowser en een server. Zodra een WebSocket-verbinding tot stand is gebracht, blijft de verbinding open totdat de client of server besluit deze verbinding te verbreken.

Een typische use case zou kunnen zijn wanneer een app meerdere gebruikers omvat die met elkaar communiceren, zoals in een chat. We zullen in ons voorbeeld een eenvoudige chatclient bouwen.

2. Maven afhankelijkheden

Aangezien dit een op Maven gebaseerd project is, voegen we eerst de vereiste afhankelijkheden toe aan het pom.xml:

 org.springframework spring-websocket 5.2.2.RELEASE org.springframework spring-messaging 5.2.2.RELEASE 

Bovendien, zoals we zullen gebruiken JSON om de hoofdtekst van onze berichten op te bouwen, moeten we de Jackson afhankelijkheden. Hierdoor kan Spring ons Java-object converteren van / naar JSON:

 com.fasterxml.jackson.core jackson-core 2.10.2 com.fasterxml.jackson.core jackson-databind 2.10.2 

Als je de nieuwste versie van de bovenstaande bibliotheken wilt downloaden, zoek ze dan op Maven Central.

3. Schakel WebSocket in het voorjaar in

Het eerste dat u moet doen, is de WebSocket-mogelijkheden inschakelen. Om dit te doen, moeten we een configuratie aan onze applicatie toevoegen en deze klasse annoteren met @EnableWebSocketMessageBroker.

Zoals de naam doet vermoeden, maakt het WebSocket-berichtafhandeling mogelijk, ondersteund door een berichtmakelaar:

@Configuration @EnableWebSocketMessageBroker openbare klasse WebSocketConfig breidt AbstractWebSocketMessageBrokerConfigurer {@Override public void configureMessageBroker (MessageBrokerRegistry-configuratie) {config.enableSimpleBroker ("/ topic"); config.setApplicationDestinationPrefixes ("/ app"); } @Override public void registerStompEndpoints (StompEndpointRegistry-register) {registry.addEndpoint ("/ chat"); registry.addEndpoint ("/ chat"). withSockJS (); }} 

Hier kunnen we zien dat de methode configureMessageBroker is gewend aan configureer de Message Broker. Ten eerste stellen we een in-memory message broker in staat om de berichten terug te sturen naar de client op bestemmingen met het voorvoegsel "/ topic".

We voltooien onze eenvoudige configuratie door het voorvoegsel '/ app' toe te wijzen om bestemmingen te filteren die zijn gericht op geannoteerde toepassingsmethoden (via @MessageMapping).

De registerStompEndpoints methode registreert het "/ chat" -eindpunt, waardoor Spring's STOMP-ondersteuning. Houd er rekening mee dat we hier ook een eindpunt toevoegen dat werkt zonder de SockJS omwille van de elasticiteit.

Dit eindpunt, wanneer het wordt voorafgegaan door "/ app", is het eindpunt dat het ChatController.send () methode is toegewezen om af te handelen.

Het ook schakelt de terugvalopties van SockJS in, zodat alternatieve berichtopties kunnen worden gebruikt als WebSockets niet beschikbaar zijn. Dit is handig omdat WebSocket nog niet in alle browsers wordt ondersteund en mogelijk wordt uitgesloten door beperkende netwerkproxy's.

Door de fallbacks kunnen de applicaties een WebSocket-API gebruiken, maar worden ze gracieus afgebroken tot niet-WebSocket-alternatieven wanneer dat nodig is tijdens runtime.

4. Maak het berichtmodel

Nu we het project hebben opgezet en de WebSocket-mogelijkheden hebben geconfigureerd, moeten we een bericht maken om te verzenden.

Het eindpunt accepteert berichten met de naam van de afzender en een tekst in een STOMP-bericht waarvan de body een JSON voorwerp.

Het bericht kan er als volgt uitzien:

{"from": "John", "text": "Hallo!" } 

Om het bericht met de tekst te modelleren, kunnen we een eenvoudig makenJava-object met van en tekst eigendommen:

openbare klasse Bericht {privé String van; private String-tekst; // getters en setters} 

Spring gebruikt standaard de Jackson bibliotheek om ons modelobject van en naar JSON te converteren.

5. Maak een Message-Handling Controller

Zoals we hebben gezien, is Spring's benadering van het werken met STOMP-berichten door een controllermethode aan het geconfigureerde eindpunt te koppelen. Dit wordt mogelijk gemaakt door de @MessageMapping annotatie.

De koppeling tussen het eindpunt en de controller geeft ons de mogelijkheid om het bericht indien nodig af te handelen:

@MessageMapping ("/ chat") @SendTo ("/ topic / messages") public OutputMessage send (Message message) genereert Uitzondering {String time = new SimpleDateFormat ("HH: mm"). Format (new Date ()); retourneer nieuwe OutputMessage (message.getFrom (), message.getText (), tijd); } 

Voor de doeleinden van ons voorbeeld maken we een ander modelobject met de naam Uitvoerbericht om het uitvoerbericht weer te geven dat naar de geconfigureerde bestemming is verzonden. We vullen ons object met de afzender en de berichttekst uit het inkomende bericht en verrijken het met een tijdstempel.

Nadat we ons bericht hebben afgehandeld, sturen we het naar de juiste bestemming die is gedefinieerd met de @Verzenden naar annotatie. Alle abonnees op de "/ topic / berichten”Bestemming ontvangt het bericht.

6. Maak een browserclient

Nadat we onze configuraties aan de serverzijde hebben gemaakt, gebruiken we de sockjs-client bibliotheek om een ​​eenvoudige HTML-pagina te bouwen die communiceert met ons berichtensysteem.

Allereerst moeten we het sockjs en stampen Javascript-clientbibliotheken. Vervolgens kunnen we een aansluiten() functie om de communicatie met ons eindpunt te openen, een bericht versturen() functie om ons STOMP-bericht en een verbinding verbreken() functie om de communicatie te sluiten:

  Chat WebSocket var stompClient = null; functie setConnected (verbonden) {document.getElementById ('connect'). disabled = verbonden; document.getElementById ('verbinding verbreken'). disabled =! verbonden; document.getElementById ('gesprekDiv'). style.visibility = verbonden? 'visible': 'verborgen'; document.getElementById ('antwoord'). innerHTML = ''; } function connect () {var socket = new SockJS ('/ chat'); stompClient = Stomp.over (socket); stompClient.connect ({}, function (frame) {setConnected (true); console.log ('Connected:' + frame); stompClient.subscribe ('/ topic / messages', function (messageOutput) {showMessageOutput (JSON.parse (messageOutput.body));});}); } functie verbreken () {if (stompClient! = null) {stompClient.disconnect (); } setConnected (false); console.log ("Verbinding verbroken"); } functie sendMessage () {var from = document.getElementById ('van'). waarde; var text = document.getElementById ('text'). waarde; stompClient.send ("/ app / chat", {}, JSON.stringify ({'from': from, 'text': text})); } functie showMessageOutput (messageOutput) {var response = document.getElementById ('response'); var p = document.createElement ('p'); p.style.wordWrap = 'breekwoord'; p.appendChild (document.createTextNode (messageOutput.from + ":" + messageOutput.text + "(" + messageOutput.time + ")")); response.appendChild (p); }

Verbinding verbreken

Sturen

7. Testen van het voorbeeld

Om ons voorbeeld te testen, kunnen we een aantal browservensters openen en de chatpagina openen op:

// localhost: 8080

Zodra dit is gebeurd, kunnen we deelnemen aan de chat door een bijnaam in te voeren en op de verbindingsknop te drukken. Als we een bericht opstellen en verzenden, kunnen we het zien in alle browsersessies die aan de chat hebben deelgenomen.

Bekijk de screenshot om een ​​voorbeeld te zien:

8. Conclusie

In deze tutorial hebben we de WebSocket-ondersteuning van Spring onderzocht. We hebben de server-side configuratie gezien en een simpele client-side tegenhanger gebouwd met behulp van sockjs en stampen Javascript-bibliotheken.

De voorbeeldcode is te vinden in het GitHub-project.