Ein kurzes Beispiel für die @ SendToUser-Annotation von Spring Websockets

1. Übersicht

In diesem kurzen Tutorial zeigen wir Ihnen, wie Sie mit Spring WebSockets eine Nachricht an eine bestimmte Sitzung oder einen bestimmten Benutzer senden .

Eine Einführung in das obige Modul finden Sie in diesem Artikel.

2. WebSocket-Konfiguration

Zunächst müssen wir unseren Nachrichtenbroker und den Endpunkt der WebSocket-Anwendung konfigurieren :

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

Mit @EnableWebSocketMessageBroker haben wir ein von Brokern unterstütztes Messaging über WebSocket mit STOMP aktiviert , das für Streaming Text Oriented Messaging Protocol steht. Es ist wichtig zu beachten, dass diese Anmerkung in Verbindung mit der @Configuration verwendet werden muss .

Es ist nicht zwingend erforderlich, den AbstractWebSocketMessageBrokerConfigurer zu erweitern, aber für das kurze Beispiel ist es einfacher, die importierte Konfiguration anzupassen.

Bei der ersten Methode haben wir einen einfachen speicherbasierten Nachrichtenbroker eingerichtet, der die Nachrichten an Zielen mit dem Präfix "/ topic" und "/ queue" zum Client zurückbringt .

Und im zweiten haben wir Stomp-Endpunkte bei "/ greeting" registriert .

Für den Fall, dass wir SockJS aktivieren möchten, müssen wir den Registerteil ändern:

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

3. Abrufen der Sitzungs-ID durch Interceptor

Eine Möglichkeit , die Sitzungs-ID zu erhalten, besteht darin, einen Spring Interceptor hinzuzufügen, der während des Handshakes ausgelöst wird und die Informationen aus den Anforderungsdaten abruft.

Dieser Interceptor kann direkt in WebSocketConfig hinzugefügt werden :

@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry .addEndpoint("/greeting") .setHandshakeHandler(new DefaultHandshakeHandler() { public boolean beforeHandshake( ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest .getServletRequest().getSession(); attributes.put("sessionId", session.getId()); } return true; }}).withSockJS(); }

4. WebSocket-Endpunkt

Ab Spring 5.0.5.RELEASE müssen keine Anpassungen vorgenommen werden, da die Annotation @SendToUser verbessert wurde , sodass wir eine Nachricht über " / user / {sessionId} / ... " an ein Benutzerziel senden können als „ / user / {user} /… “.

Das bedeutet, dass die Anmerkung basierend auf der Sitzungs-ID der Eingabenachricht funktioniert und effektiv eine Antwort an ein privates Ziel an die Sitzung sendet:

@Controller public class WebSocketController { @Autowired private SimpMessageSendingOperations messagingTemplate; private Gson gson = new Gson(); @MessageMapping("/message") @SendToUser("/queue/reply") public String processMessageFromClient( @Payload String message, Principal principal) throws Exception { return gson .fromJson(message, Map.class) .get("name").toString(); } @MessageExceptionHandler @SendToUser("/queue/errors") public String handleException(Throwable exception) { return exception.getMessage(); } }

Es ist wichtig zu bemerken, dass @SendToUser angibt, dass der Rückgabewert einer Nachrichtenbehandlungsmethode als Nachricht an die angegebenen Ziele gesendet werden soll, denen " / user / {Benutzername} " vorangestellt ist .

5. WebSocket Client

function connect() { var socket = new WebSocket('ws://localhost:8080/greeting'); ws = Stomp.over(socket); ws.connect({}, function(frame) { ws.subscribe("/user/queue/errors", function(message) { alert("Error " + message.body); }); ws.subscribe("/user/queue/reply", function(message) { alert("Message " + message.body); }); }, function(error) { alert("STOMP error " + error); }); } function disconnect() { if (ws != null) { ws.close(); } setConnected(false); console.log("Disconnected"); }

Es wird ein neues WebSocket erstellt, das auf " / greeting " für die Zuordnung in WebSocketConfiguration verweist .

Wenn wir den Client für " / user / queue / Errors " und " / user / queue / reply " abonnieren, verwenden wir die kommentierten Informationen aus dem letzten Abschnitt.

Wie wir sehen können, zeigt @SendToUser auf " Warteschlange / Fehler ", aber die Nachricht wird an " / Benutzer / Warteschlange / Fehler " gesendet .

6. Fazit

In diesem Artikel haben wir eine Möglichkeit untersucht, eine Nachricht mit Spring WebSocket direkt an einen Benutzer oder eine Sitzungs-ID zu senden

Wie immer ist der vollständige Quellcode der Beispiele auf GitHub verfügbar.