2016-08-02 23 views
2

Heute habe ich ein paar Stunden für eine Implementierung oder ein Tutorial gesucht, wie man WebSocket-Verbindungen im Frühling behält.Websocket halten Verbindungen von Verbindungen in Frühling

Ich habe das (sehr gute) Spring Tutorial über Websockets und STOMP gemacht.

Also, was ist mein Setup, ich habe eine Ionic Hybrid App mit einem Spring-Backend und ich möchte eine Benachrichtigung an den Client senden, wenn ein neues Benachrichtigungsereignis im Backend auftritt. All dieser Code ist bereits implementiert und die Verbindung funktioniert, aber momentan gibt es keine Möglichkeit anzugeben, wohin die Benachrichtigungen gehen sollen.

Es gibt kein Tutorial oder eine Erklärung in dieser Angelegenheit, die der Struktur im Spring Tutorial folgt (zumindest nicht nach 5 Stunden Forschung) und ich bin ein wenig überwältigt von all den Informationen über Websockets und Sicherheit im Web. (Ich habe über Websockets für nur 2 Tage gelernt)

Also für alle das war vor mir und wird nach mir kommen, ich denke, es kann sehr nützlich sein, eine kompakte und leichte Antwort nach der Struktur von der gelehrt Frühling Tutorial.

Ich habe this unanswered question auf StackOverflow über die gleichen Probleme wie ich, so bin ich sicher, dass diese Fragen beweisen, dass es sich lohnt.

TL; DR

Wie eine Liste im Backend implementieren, die auf der Spring WebSocket Tutorial basierend Spur der Anschlüsse hält?

Wie werden Daten vom Client an das Backend gesendet, wenn die Verbindung hergestellt wurde? (z. B. eine Benutzer-ID oder ein Token)

+0

Haben Sie sich tatsächlich die Zeit genommen, das [Referenzhandbuch] zu lesen (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-server-handshake) –

+0

Ich tat, und wie ich schon sagte, es war alles überwältigend, daher denke ich, dass eine einfache und universelle Antwort für neue Lernende wie mich sehr nützlich sein könnte. – Sytham

Antwort

1

Also habe ich es selbst herausgefunden.

Meine Benachrichtigungen haben einen Empfänger-ID (die Benutzer-ID, wo die Benachrichtigungen zu senden werden muss)

So zu ‚/ ws-user /‘ senden Ich werde + id + ‚/ Grüße‘, wo die ID ist der Benutzer, der angemeldet ist.

Auf der Clientseite ist dies ziemlich einfach zu erreichen.

var stompClient = null; 

    // init 
    function init() { 
      /** 
      * Note that you need to specify your ip somewhere globally 
      **/ 
     var socket = new SockJS('http://127.0.0.1:9080/ws-notification'); 
     stompClient = Stomp.over(socket); 
     stompClient.connect({}, function(frame) { 
      console.log('Connected: ' + frame); 
      /** 
      * This is where I get the id of the logged in user 
      **/ 
      barService.currentBarAccountStore.getValue().then(function (barAccount) { 
       subscribeWithId(stompClient,barAccount.user.id); 
      }); 
     }); 
    } 

      /** 
      * subscribe at the url with the userid 
      **/ 
    function subscribeWithId(stompClient,id){ 
     stompClient.subscribe('/ws-user/'+id+'/greetings', function(){ 
      showNotify(); 
     }); 
    } 
      /** 
      * Broadcast over the rootscope to update the angular view 
      **/ 
    function showNotify(){ 
     $rootScope.$broadcast('new-notification'); 
    } 

    function disconnect() { 
     if (stompClient != null) { 
      stompClient.disconnect(); 
     } 
     // setConnected(false); 
     console.log("Disconnected"); 
    } 

Als nächstes fügen wir „setUserDestinationPrefix“ der MessageBrokerRegistry in der WebSocketConfig.java Klasse:

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 

    private final static String userDestinationPrefix = "/ws-user/"; 

    @Override 
    public void configureMessageBroker(MessageBrokerRegistry config){ 
     config.enableSimpleBroker("/ws-topic","/ws-user"); 
     config.setApplicationDestinationPrefixes("/ws-app"); 
     config.setUserDestinationPrefix(userDestinationPrefix); 
    } 

    @Override 
    public void registerStompEndpoints(StompEndpointRegistry registry) { 
     registry.addEndpoint("/ws-notification").setAllowedOrigins("*").withSockJS(); 
    } 
} 

Bitte beachte, dass ich interne RestTemplate bin mit ruft meine controllermethod zuzugreifen, die eine Benachrichtigung sendet an der abonnierte Client.Dies wird durch eine Event-Consumer-Klasse getan (fragen Sie den Code zu sehen, es ist nur Controller-Funktion auszulösen, anders gemacht werden könnte)

@RequestMapping(value = "/test-notification", method = RequestMethod.POST) 
public void testNotification(@RequestBody String recipientId) throws InterruptedException { 
    this.template.convertAndSendToUser(recipientId,"/greetings", new Notify("ALERT: There is a new notification for you!")); 
} 

Bitte meinen Code überprüfen und mir warnen, wenn Sie irgendwelche Probleme sehen und/oder Sicherheitsbedenken .

+0

Können Sie den Code teilen? Woher wissen Sie, welcher Socket zum Senden der Nachricht an den Client verwendet werden soll? –

0

Für die benutzerbasierte Zustellung in Websocket können Sie Prinzipobjekte mit Federsicherheit verwenden. Hier ist ein schönes Beispiel implementiert:

https://github.com/rstoyanchev/spring-websocket-portfolio

Frühling Sicherheit für denselben Ursprung überprüfen wird und von Ihrem Client können Sie die Stomp-Header mit Used-ID angegeben senden.

Hoffe, das könnte Ihnen helfen.