Een snel voorbeeld van de @SendToUser-annotatie van Spring Websockets

1. Overzicht

In deze korte tutorial gaan we het illustreren hoe u met Spring WebSockets een bericht naar een specifieke sessie of een bepaalde gebruiker stuurt.

Raadpleeg dit artikel voor een inleiding op de bovenstaande module.

2. WebSocket-configuratie

Allereerst moeten we configureer onze Message Broker en WebSocket-applicatie-eindpunt:

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

Met @EnableWebSocketMessageBroker wij heeft een door een makelaar ondersteund bericht via WebSocket ingeschakeld met behulp van STOMP, wat staat voor Streaming Text Oriented Messaging Protocol. Het is belangrijk op te merken dat deze annotatie moet worden gebruikt in combinatie met de @Configuratie.

Het is niet verplicht om het AbstractWebSocketMessageBrokerConfigurer maar voor het snelle voorbeeld is het gemakkelijker om de geïmporteerde configuratie aan te passen.

Bij de eerste methode hebben we een eenvoudige, op geheugen gebaseerde berichtenmakelaar opgezet om de berichten terug te sturen naar de klant op bestemmingen met het voorvoegsel "/onderwerp" en "/wachtrij".

En in de tweede hebben we stomp-eindpunten geregistreerd op "/groet".

In het geval dat we SockJS willen inschakelen, moeten we het registergedeelte aanpassen:

registry.addEndpoint ("/ groet"). withSockJS ();

3. Verkrijg sessie-ID door Interceptor

Een manier om de sessie-id te verkrijgen voegt een Spring Interceptor toe die wordt geactiveerd tijdens de handshake en de informatie uit de verzoekgegevens haalt.

Deze interceptor kan rechtstreeks worden toegevoegd aan WebSocketConfig:

@Override public void registerStompEndpoints (StompEndpointRegistry-register) {registry .addEndpoint ("/ greeting") .setHandshakeHandler (nieuwe DefaultHandshakeHandler () {public boolean beforeHandshake (ServerHttpRequest-verzoek, ServerHttpRespResponseof-instantie, ServerHttpResponseof-instantie, ServerHttpResponseof-aanvraag, ServerHttpResponseof-antwoord, ServerHttpResponseof-instantie ServletServerHttpRequest) {ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) verzoek; HttpSession-sessie = servletRequest .getServletRequest (). GetSession (); attributes.put ("sessionId", session.getId ());} retourneren waar; }JS). ; }

4. WebSocket-eindpunt

Vanaf Spring 5.0.5.RELEASE is het niet nodig om aanpassingen te doen vanwege de verbetering van @SendToUser annotatie, waarmee we een bericht naar een gebruikersbestemming kunnen sturen via "/ user / {sessionId} /…" liever dan "/ user / {user} /…“.

Dat betekent dat de annotatie werkt op basis van de sessie-id van het invoerbericht, waardoor in feite een antwoord wordt verzonden naar een privébestemming voor de sessie:

@Controller openbare klasse WebSocketController {@Autowired privé SimpMessageSendingOperations messagingTemplate; private Gson gson = nieuwe Gson (); @MessageMapping ("/ message") @SendToUser ("/ queue / reply") public String processMessageFromClient (@Payload String-bericht, Principal-principal) genereert Uitzondering {return gson .fromJson (bericht, Map.class) .get ("naam" ) .toString (); } @MessageExceptionHandler @SendToUser ("/ queue / errors") openbare String handleException (Throwable-uitzondering) {return exception.getMessage (); }}

Het is belangrijk om op te merken dat, @SendToUser geeft aan dat de retourwaarde van een berichtafhandelingsmethode moet worden verzonden als een Bericht aan de gespecificeerde bestemming (en) voorafgegaan door '/ user / {gebruikersnaam}.

5. WebSocket-client

function connect () {var socket = new WebSocket ('ws: // localhost: 8080 / groet'); ws = Stomp.over (socket); ws.connect ({}, functie (frame) {ws.subscribe ("/ gebruiker / wachtrij / fouten", functie (bericht) {alert ("Fout" + bericht.body);}); ws.subscribe ("/ gebruiker / wachtrij / antwoord ", functie (bericht) {alert (" Bericht "+ message.body);});}, functie (fout) {alert (" STOMP-fout "+ fout);}); } functie verbreken () {if (ws! = null) {ws.close (); } setConnected (false); console.log ("Verbinding verbroken"); }

Een nieuw WebSocket is gemaakt wijzend naar “/groet”Voor het in kaart brengen in WebSocketConfiguration.

Wanneer we de klant abonneren op “/ gebruiker / wachtrij / fouten"En"/ gebruiker / wachtrij / antwoord”Is waar we de opgemerkte informatie uit de laatste sectie gebruiken.

Zoals we kunnen zien, @SendToUser wijst naar "wachtrij / fouten'Maar het bericht wordt verzonden naar'/ gebruiker / wachtrij / fouten“.

6. Conclusie

In dit artikel hebben we een manier onderzocht om een ​​bericht rechtstreeks naar een gebruiker of sessie-ID te sturen met Spring WebSocket

Zoals altijd is de volledige broncode van de voorbeelden beschikbaar op GitHub.