Spring WebSockets: Send meldinger til en bestemt bruker

1. Introduksjon

I denne opplæringen vil vi beskrive hvordan du gjør det bruk Spring WebSockets til å sende STOMP-meldinger til en enkelt bruker. Det er viktig fordi vi noen ganger ikke vil kringkaste alle meldinger til hver bruker. I tillegg til det, vil vi demonstrere hvordan du sender disse meldingene på en sikker måte.

For en introduksjon til WebSockets, sjekk ut denne flotte opplæringen for hvordan du kommer i gang. Og for å få et dypere dykk i sikkerhet, sjekk ut denne artikkelen for å sikre implementeringen av WebSockets.

2. Køer, emner og sluttpunkter

Det er tre hovedmåter å si hvor meldinger sendes og hvordan de abonnerer på ved hjelp av Spring WebSockets og STOMP:

  1. Temaer - vanlige samtaler eller chat-emner som er åpne for enhver klient eller bruker
  2. Køer - reservert for bestemte brukere og deres nåværende økter
  3. Endepunkter - generiske endepunkter

La oss ta en rask titt på et eksempel på en kontekstbane for hver:

  • “/ Emne / filmer”
  • “/ Bruker / kø / spesifikk bruker”
  • “/ Sikret / chat”

Det er viktig å merke seg det vi må bruke køer for å sende meldinger til bestemte brukere, ettersom emner og sluttpunkter ikke støtter denne funksjonaliteten.

3. Konfigurasjon

La oss nå lære hvordan vi konfigurerer applikasjonen vår slik at vi kan sende meldinger til en bestemt bruker:

offentlig klasse SocketBrokerConfig utvider AbstractWebSocketMessageBrokerConfigurer {@Override public void configureMessageBroker (MessageBrokerRegistry config) {config.enableSimpleBroker ("/ secure / user / queue / specific-user"); config.setApplicationDestinationPrefixes ("/ spring-security-mvc-socket"); config.setUserDestinationPrefix ("/ sikret / bruker"); } @ Override public void registerStompEndpoints (StompEndpointRegistry registry) {registry.addEndpoint ("/ secure / room"). WithSockJS (); }}

La oss sørge for å inkludere en brukerdestinasjon siden det bestemmer hvilke sluttpunkter som er reservert for enkeltbrukere.

Vi prefikser også alle våre køer og brukerdestinasjoner med “/ Sikret” for å få dem til å kreve autentisering. For ubeskyttede sluttpunkter kan vi slippe “/ Sikret” prefikset (som et resultat av våre andre sikkerhetsinnstillinger).

Fra en pom.xml synspunkt, det kreves ingen ekstra avhengigheter.

4. URL-kartlegginger

Vi vil at klienten skal abonnere på en kø ved hjelp av en URL-kartlegging som samsvarer med følgende mønster:

"/ bruker / kø / oppdateringer"

Denne kartleggingen blir automatisk transformert av UserDestinationMessageHandler inn i den brukerøktespesifikke adressen.

For eksempel hvis vi har en bruker som heter “Bruker123”vil den tilsvarende adressen være:

"/ kø / oppdateringer-bruker123"

På serversiden sender vi vårt brukerspesifikke svar ved hjelp av følgende URL-kartleggingsmønster:

"/ bruker / {brukernavn} / kø / oppdateringer"

Dette vil også bli forvandlet til riktig nettadressekartlegging vi allerede abonnerte på klientsiden.

Dermed ser vi det de viktigste ingrediensene her er to ganger:

  1. Forbered vårt spesifiserte brukerdestinasjonsprefiks (konfigurert i AbstractWebSocketMessageBrokerConfigurer).
  2. Bruk "/kø" et sted innenfor kartleggingen.

I neste avsnitt vil vi se nøyaktig hvordan du gjør dette.

5. Påkalle convertAndSendToUser ()

Vi kan ikke statisk påberope oss convertAndSendToUser () fra SimpMessagingTemplate eller SimpMessageSendingOperations:

@Autowired private SimpMessagingTemplate simpMessagingTemplate; @MessageMapping ("/ secure / room") public void sendSpecific (@Payload Message msg, Main user, @Header ("simpSessionId") Streng sessionId) kaster Unntak {OutputMessage out = new OutputMessage (msg.getFrom (), msg.getText (), nytt SimpleDateFormat ("HH: mm"). format (ny dato ())); simpMessagingTemplate.convertAndSendToUser (msg.getTo (), "/ sikret / bruker / kø / spesifikk bruker", ut); }

Du har kanskje lagt merke til:

@Header ("simpSessionId") Streng sessionId

De @Overskrift kommentar gir tilgang til overskrifter eksponert av den innkommende meldingen. For eksempel kan vi ta tak i strømmen øktnummer uten behov for kompliserte avlyttere. På samme måte, vi kan få tilgang til den nåværende brukeren via Rektor.

Det er viktig at tilnærmingen vi tar i denne artikkelen gir større tilpasning i forhold til @sendToUser kommentar med hensyn til URL-kartlegginger. For mer om den kommentaren, sjekk ut denne flotte artikkelen.

Vi bruker klientsiden koble() i JavaScript til initialisere en SockJS-forekomst og koble til vår WebSocket-server ved hjelp av STOMP:

var socket = ny SockJS ('/ sikret / rom'); var stompClient = Stomp.over (stikkontakt); var sessionId = ""; stompClient.connect ({}, funksjon (ramme) {var url = stompClient.ws._transport.url; url = url.replace ("ws: // localhost: 8080 / spring-security-mvc-socket / secure / room / "," "); url = url.replace (" / websocket "," "); url = url.replace (/ ^ [0-9] + \ //," "); console.log (" Your current økt er: "+ url); sessionId = url;} 

Vi får også tilgang til den medfølgende øktnummer og legg det til “ sikret / rom URL-kartlegging. Dette gir oss muligheten til å levere en brukerspesifikk abonnementskø dynamisk og manuelt:

stompClient.subscribe ('sikret / bruker / kø / spesifikk bruker' + '-bruker' + that.sessionId, funksjon (msgOut) {// håndter meldinger} 

Når alt er satt opp, bør vi se:

Og i serverkonsollen vår:

6. Konklusjon

Sjekk ut den offisielle vårbloggen og den offisielle dokumentasjonen for mer informasjon om dette emnet.

Som alltid er kodeeksemplene som brukes i denne artikkelen tilgjengelig på GitHub.


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