wake-up-neo.com

Pfadvariablen in Spring WebSockets @SendTo-Zuordnung

Ich habe, was ich denke, eine sehr einfache Spring WebSocket-Anwendung. Ich versuche jedoch, Pfadvariablen sowohl für die Subskription als auch für die Nachrichtenzuordnung zu verwenden.

Ich habe unten ein paraphrasiertes Beispiel gepostet. Ich würde erwarten, dass die Annotation @SendTo zu den Abonnenten zurückkehrt, basierend auf ihrer fleetId. Das heißt, eine POST in /fleet/MyFleet/driver/MyDriver sollte die Abonnenten über /fleet/MyFleet informieren, aber ich sehe dieses Verhalten nicht.

Es ist erwähnenswert, dass das Abonnieren von /fleet/{fleetId} wörtlich funktioniert. Ist das beabsichtigt? Fehlt mir etwas Konfiguration? Oder funktioniert das einfach nicht so?

Ich bin mit WebSockets oder diesem Spring-Projekt noch nicht sehr vertraut, daher vielen Dank im Voraus.

Controller.Java

...
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
    return new Simple(fleetId, driverId);
}
...

WebSocketConfig.Java

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/live");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/fleet").withSockJS();
    }
}

index.html

var socket = new SockJS('/fleet');
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
    // Doesn't Work
    stompClient.subscribe('/topic/fleet/MyFleet', function(greeting) {
    // Works
    stompClient.subscribe('/topic/fleet/{fleetId}', function(greeting) {
        // Do some stuff
    });
});

Probe senden

    stompClient.send("/live/fleet/MyFleet/driver/MyDriver", {}, JSON.stringify({
        // Some simple content
    }));
34
bvulaj

Obwohl @MessageMapping Platzhalter unterstützt, werden sie in @SendTo-Zielen nicht angezeigt/aufgelöst. Momentan gibt es keine Möglichkeit, dynamische Ziele mit der Annotation @SendTo zu definieren (siehe Ausgabe SPR-12170 ). Sie können die SimpMessagingTemplate vorerst verwenden (so funktioniert es sowieso intern). So würden Sie es tun:

@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
public void simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
    simpMessagingTemplate.convertAndSend("/topic/fleet/" + fleetId, new Simple(fleetId, driverId));
}

In Ihrem Code wird das Ziel '/ topic/fleet/{fleetId}' als Literal behandelt. Aus diesem Grund funktioniert das Abonnieren des Ziels, nur weil Sie an dasselbe Ziel senden.

Wenn Sie nur einige benutzerspezifische Daten senden möchten, können Sie diese direkt im Abonnement zurückgeben:

@SubscribeMapping("/fleet/{fleetId}/driver/{driverId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
    return new Simple(fleetId, driverId);
}

Update: In Spring 4.2 werden Platzhalter für Zielvariablen unterstützt. Jetzt können Sie Folgendes tun:

@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
    return new Simple(fleetId, driverId);
}
81
Sergi Almar

sie können eine Variable innerhalb des Pfads senden. Zum Beispiel sende ich "este/es/el/chat/Java /" und vermerkte den Server als "este: es: el: chat: Java: "

klient:

stompSession.send("/app/chat/este/es/el/chat/Java/*", ...);

server:

@MessageMapping("/chat/**")
@SendToUser("/queue/reply")
public WebsocketData greeting(Message m,HelloMessage message,@Header("simpSessionId") String sessionId) throws Exception {
    Map<String, LinkedList<String>> nativeHeaders = (Map<String, LinkedList<String>>) m.getHeaders().get("nativeHeaders");
    String value= nativeHeaders.get("destination").getFirst().replaceAll("/app/chat/","").replaceAll("/",":");
0
ivan rc