Einführung in WebSockets mit Spring

1. Übersicht

In diesem Artikel erstellen wir eine einfache Webanwendung, die Messaging mithilfe der neuen WebSocket-Funktionen implementiert, die mit Spring Framework 4.0 eingeführt wurden.

WebSockets ist eine bi-direktionalen , Vollduplex , dauerhafte Verbindung zwischen einem Web - Browser und einem Server. Sobald eine WebSocket-Verbindung hergestellt ist, bleibt die Verbindung geöffnet, bis der Client oder Server beschließt, diese Verbindung zu schließen.

Ein typischer Anwendungsfall kann sein, wenn eine App mehrere Benutzer umfasst, die wie in einem Chat miteinander kommunizieren. In unserem Beispiel erstellen wir einen einfachen Chat-Client.

2. Maven-Abhängigkeiten

Da es sich um ein Maven-basiertes Projekt handelt, fügen wir der pom.xml zunächst die erforderlichen Abhängigkeiten hinzu :

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

Da wir JSON verwenden , um den Textkörper unserer Nachrichten zu erstellen, müssen wir außerdem die Jackson- Abhängigkeiten hinzufügen . Dadurch kann Spring unser Java-Objekt in / von JSON konvertieren :

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

Wenn Sie die neueste Version der oben genannten Bibliotheken erhalten möchten, suchen Sie sie in Maven Central.

3. Aktivieren Sie WebSocket im Frühjahr

Als Erstes müssen Sie die WebSocket-Funktionen aktivieren. Dazu müssen wir unserer Anwendung eine Konfiguration hinzufügen und diese Klasse mit @EnableWebSocketMessageBroker versehen .

Wie der Name schon sagt, ermöglicht es die WebSocket-Nachrichtenverarbeitung, die von einem Nachrichtenbroker unterstützt wird:

@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chat"); registry.addEndpoint("/chat").withSockJS(); } } 

Hier sehen wir, dass die Methode configureMessageBroker zum Konfigurieren des Nachrichtenbrokers verwendet wird . Zunächst aktivieren wir einen In-Memory-Nachrichtenbroker, der die Nachrichten an Zielen mit dem Präfix „/ topic“ zum Client zurückbringt.

Wir vervollständigen unsere einfache Konfiguration, indem wir das Präfix "/ app" festlegen , um Ziele zu filtern, die auf mit Anwendungen kommentierte Methoden abzielen (über @MessageMapping ).

Die registerStompEndpoints Methode registriert den „/ chat“ Endpunkt, ermöglicht Spring STOMP Unterstützung . Beachten Sie, dass wir hier auch einen Endpunkt hinzufügen, der aus Gründen der Elastizität ohne SockJS funktioniert.

Wenn diesem Endpunkt das Präfix "/ app" vorangestellt wird, ist dies der Endpunkt, dem die ChatController.send () -Methode zugeordnet ist.

Außerdem werden die SockJS-Fallback-Optionen aktiviert, sodass alternative Messaging-Optionen verwendet werden können, wenn WebSockets nicht verfügbar sind. Dies ist nützlich, da WebSocket noch nicht in allen Browsern unterstützt wird und möglicherweise durch restriktive Netzwerkproxys ausgeschlossen wird.

Durch die Fallbacks können die Anwendungen eine WebSocket-API verwenden, werden jedoch bei Bedarf zur Laufzeit ordnungsgemäß auf Nicht-WebSocket-Alternativen herabgesetzt.

4. Erstellen Sie das Nachrichtenmodell

Nachdem wir das Projekt eingerichtet und die WebSocket-Funktionen konfiguriert haben, müssen wir eine Nachricht zum Senden erstellen.

Der Endpunkt akzeptiert Nachrichten, die den Absendernamen und einen Text in einer STOMP-Nachricht enthalten, deren Hauptteil ein JSON- Objekt ist.

Die Nachricht könnte folgendermaßen aussehen:

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

Um die Nachricht mit dem Text zu modellieren, können wir eine einfache erstellenJava - Objekt mit aus und Texteigenschaften:

public class Message { private String from; private String text; // getters and setters } 

Standardmäßig verwendet Spring die Jackson- Bibliothek, um unser Modellobjekt in und von JSON zu konvertieren.

5. Erstellen Sie einen Message-Handling-Controller

Wie wir gesehen haben, besteht der Ansatz von Spring bei der Arbeit mit STOMP-Messaging darin, dem konfigurierten Endpunkt eine Controller-Methode zuzuordnen. Dies wird durch die Annotation @MessageMapping ermöglicht .

Die Zuordnung zwischen dem Endpunkt und dem Controller gibt uns die Möglichkeit, die Nachricht bei Bedarf zu verarbeiten:

@MessageMapping("/chat") @SendTo("/topic/messages") public OutputMessage send(Message message) throws Exception { String time = new SimpleDateFormat("HH:mm").format(new Date()); return new OutputMessage(message.getFrom(), message.getText(), time); } 

Für die Zwecke unseres Beispiels erstellen wir ein weiteres Modellobjekt mit dem Namen OutputMessage , um die an das konfigurierte Ziel gesendete Ausgabenachricht darzustellen. Wir füllen unser Objekt mit dem Absender und dem Nachrichtentext aus der eingehenden Nachricht und bereichern es mit einem Zeitstempel.

Nachdem wir unsere Nachricht bearbeitet haben , senden wir sie an das entsprechende Ziel, das mit der Annotation @SendTo definiert wurde . Alle Abonnenten des Ziels " / topic / messages " erhalten die Nachricht.

6. Erstellen Sie einen Browser-Client

Nachdem wir unsere Konfigurationen auf der Serverseite vorgenommen haben, verwenden wir die sockjs-client-Bibliothek , um eine einfache HTML-Seite zu erstellen, die mit unserem Nachrichtensystem interagiert.

Zunächst müssen wir die Sockjs importieren und die Javascript- Clientbibliotheken stampfen . Als Nächstes können wir eine connect () - Funktion zum Öffnen der Kommunikation mit unserem Endpunkt, eine sendMessage () - Funktion zum Senden unserer STOMP-Nachricht und eine connect () - Funktion zum Schließen der Kommunikation erstellen :

  Chat WebSocket    var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; document.getElementById('response').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)); }); }); } function disconnect() { if(stompClient != null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } function sendMessage() { var from = document.getElementById('from').value; var text = document.getElementById('text').value; stompClient.send("/app/chat", {}, JSON.stringify({'from':from, 'text':text})); } function showMessageOutput(messageOutput) { var response = document.getElementById('response'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.appendChild(document.createTextNode(messageOutput.from + ": " + messageOutput.text + " (" + messageOutput.time + ")")); response.appendChild(p); }

Connect Disconnect

Send

7. Testen des Beispiels

Um unser Beispiel zu testen, können wir einige Browserfenster öffnen und auf die Chat-Seite zugreifen unter:

//localhost:8080

Sobald dies erledigt ist, können wir dem Chat beitreten, indem wir einen Spitznamen eingeben und auf die Schaltfläche "Verbinden" klicken. Wenn wir eine Nachricht verfassen und senden, können wir sie in allen Browsersitzungen sehen, die dem Chat beigetreten sind.

Schauen Sie sich den Screenshot an, um ein Beispiel zu sehen:

8. Fazit

In diesem Tutorial haben wir die WebSocket-Unterstützung von Spring untersucht. Wir haben die serverseitige Konfiguration gesehen und ein einfaches clientseitiges Gegenstück unter Verwendung von sockjs und Stomp- Javascript-Bibliotheken erstellt.

Der Beispielcode befindet sich im GitHub-Projekt.