Spring WebSockets: slanje poruka određenom korisniku

1. Uvod

U ovom uputstvu opisat ćemo kako koristite Spring WebSockets za slanje STOMP poruka jednom korisniku. To je važno jer ponekad ne želimo emitirati svaku poruku svakom korisniku. Osim toga, pokazat ćemo kako te poruke poslati na siguran način.

Za uvod u WebSockets pogledajte ovaj sjajni vodič kako započeti s radom. Da biste dublje zašli u sigurnost, pogledajte ovaj članak kako biste osigurali implementaciju WebSockets.

2. Redovi čekanja, teme i krajnje točke

Tamo su tri glavna načina kako reći gdje se poruke šalju i na koji način su pretplaćene koristeći Spring WebSockets i STOMP:

  1. Teme - uobičajeni razgovori ili teme razgovora otvorene za bilo kojeg klijenta ili korisnika
  2. Redovi - rezervirano za određene korisnike i njihove trenutne sesije
  3. Krajnje točke - generičke krajnje točke

Sada, pogledajmo na primjer primjer kontekstnog puta za svaki:

  • “/ Tema / filmovi”
  • “/ User / queue / specific-user”
  • “/ Osigurano / chat”

Važno je to napomenuti moramo koristiti redove za slanje poruka određenim korisnicima, jer teme i krajnje točke ne podržavaju ovu funkciju.

3. Konfiguracija

Sada, naučimo kako konfigurirati našu aplikaciju tako da možemo slati poruke određenom korisniku:

javna klasa SocketBrokerConfig proširuje AbstractWebSocketMessageBrokerConfigurer {@Override javnu prazninu configureMessageBroker (MessageBrokerRegistry config) {config.enableSimpleBroker ("/ osiguran / korisnik / red / specifični korisnik"); config.setApplicationDestinationPrefixes ("/ spring-security-mvc-socket"); config.setUserDestinationPrefix ("/ osiguran / korisnik"); } @Override public void registerStompEndpoints (Registar StompEndpointRegistry) {registry.addEndpoint ("/ osiguran / soba"). WithSockJS (); }}

Obavezno uključimo korisničko odredište jer to određuje koje su krajnje točke rezervirane za pojedinačne korisnike.

Također, ispred svih redova i korisničkih odredišta stavljamo oznake “/ Osigurano” da bi im bila potrebna autentifikacija. Za nezaštićene krajnje točke možemo ispustiti “/ Osigurano” prefiks (kao rezultat ostalih sigurnosnih postavki).

Od pom.xml stajalište, nisu potrebne dodatne ovisnosti.

4. Mapiranje URL-ova

Želimo da se naš klijent pretplati na red koristeći mapiranje URL-a koje je u skladu sa sljedećim uzorkom:

"/ user / queue / updates"

Ovo mapiranje automatski će transformirati UserDestinationMessageHandler na adresu specifičnu za korisničku sesiju.

Na primjer, ako imamo korisnika s imenom "Korisnik123", odgovarajuća adresa bila bi:

"/ queue / updates-user123"

Na strani poslužitelja poslat ćemo odgovor specifičan za korisnika koristeći sljedeći obrazac mapiranja URL-a:

"/ user / {korisničko ime} / red / ažuriranja"

I ovo će se pretvoriti u ispravno mapiranje URL-a na koje smo se već pretplatili na strani klijenta.

Dakle, to vidimo ovdje su bitni sastojci dvostruki:

  1. Dodajte naš navedeni prefiks odredišta korisnika (konfiguriran u AbstractWebSocketMessageBrokerConfigurer).
  2. Koristiti "/red" negdje unutar mapiranja.

U sljedećem ćemo odjeljku pogledati kako to točno učiniti.

5. Pozivanje convertAndSendToUser ()

Možemo se statički pozivati convertAndSendToUser () iz SimpMessagingTemplate ili SimpMessageSendingOperations:

@Autowired private SimpMessagingTemplate simpMessagingTemplate; @MessageMapping ("/ secured / room") javna praznina sendSpecific (@Payload Message msg, Glavni korisnik, @Header ("simpSessionId") String sessionId) baca izuzetak {OutputMessage out = new OutputMessage (msg.getFrom (), msg.getText (), novi SimpleDateFormat ("HH: mm"). format (novi datum ())); simpMessagingTemplate.convertAndSendToUser (msg.getTo (), "/ secured / user / queue / specific-user", out); }

Možda ste primijetili:

@Header ("simpSessionId") Niz sessionId

The @Zaglavlje napomena omogućuje pristup zaglavljima izloženim dolaznom porukom. Na primjer, možemo zgrabiti struju sessionId bez potrebe za kompliciranim presretačima. Slično tome, možemo pristupiti trenutnom korisniku putem Glavni.

Važno je da pristup koji koristimo u ovom članku pruža veću prilagodbu u odnosu na @sendToUser napomena s obzirom na mapiranje URL-a. Više o toj bilješci potražite u ovom sjajnom članku.

Na strani klijenta, mi ćemo koristiti Spojiti() u JavaScript-u do inicijalizirajte instancu SockJS i povežite se s našim WebSocket poslužiteljem pomoću STOMP-a:

var socket = novi SockJS ('/ osiguran / soba'); var stompClient = Stomp.over (socket); var sessionId = ""; stompClient.connect ({}, funkcija (okvir) {var url = stompClient.ws._transport.url; url = url.replace ("ws: // localhost: 8080 / spring-security-mvc-socket / secured / room / "," "); url = url.replace (" / websocket "," "); url = url.replace (/ ^ [0-9] + \ //," "); console.log (" Vaša trenutna session je: "+ url); sessionId = url;} 

Također pristupamo isporučenom sessionId i dodati to na " osiguran / soba Mapiranje URL-a. To nam daje mogućnost dinamičkog i ručnog isporučivanja korisničkog reda pretplate:

stompClient.subscribe ('osiguran / korisnik / red / određeni korisnik' + '-korisnik' + taj.sessionId, funkcija (msgOut) {// obrada poruka} 

Kad se sve postavi, trebali bismo vidjeti:

I na našoj poslužiteljskoj konzoli:

6. Zaključak

Više informacija o ovoj temi potražite na službenom proljetnom blogu i službenoj dokumentaciji.

Kao i uvijek, uzorci koda korišteni u ovom članku dostupni su na GitHubu.