Ein schnelles Beispiel der @SendToUser-Anmerkung von Spring Websockets

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

1. Überblick

In diesem kurzen Tutorial werden wirhow to send a message to a specific session or particular user using Spring WebSockets veranschaulichen.

Eine Einführung in das obige Modul finden Sie unterto this article.

2. WebSocket-Konfiguration

Zunächst müssen wirconfigure our message broker and WebSocket application endpoint:

@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 wirenabled a broker-backed messaging over WebSocket using*STOMP*,, was fürStreaming Text Oriented Messaging Protocol. It’s important to remark that this annotation needs to be used in conjunction with the @Configuration steht

Es ist nicht zwingend erforderlich,AbstractWebSocketMessageBrokerConfigurerzu 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 von Interceptor

Eine Möglichkeitto obtain the session id besteht darin, einen Spring Interceptor hinzuzufügen, der während des Handshakes ausgelöst wird und die Informationen aus den Anforderungsdaten erhält.

Dieser Interceptor kann direkt inWebSocketConfig: 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 Endpoint

Ab Spring 5.0.5.RELEASE ist keine Anpassung erforderlich, da@SendToUser annotation, that allows us to send a message to a user destination über "/user/{sessionId}/…" und nicht über "/user/{user}/…" verbessert wird.

Das bedeutet, dass die Annotation auf der Sitzungs-ID der Eingabenachricht basiert und effektiv eine Antwort an das private 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 alsMessage an die angegebenendestination(s) prepended with “/user/{username} gesendet werden soll.

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");
}

Für die Zuordnung inWebSocketConfiguration wird ein neuesWebSocket erstellt, das auf "/greeting" zeigt.

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 "queue/errors", aber die Nachricht wird an "/user/queue/errors" 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 Beispieleover on GitHub verfügbar.