簡體   English   中英

Spring WebSockets @SendTo 映射中的路徑變量

[英]Path variables in Spring WebSockets @SendTo mapping

我有一個非常簡單的 Spring WebSocket 應用程序。 但是,我正在嘗試將路徑變量用於訂閱以及消息映射。

我在下面發布了一個釋義示例。 我希望@SendTo注釋根據他們的fleetId返回給訂閱者。 即, POST/fleet/MyFleet/driver/MyDriver應該通知訂閱者/fleet/MyFleet ,但我沒有看到這種行為。

值得注意的是,訂閱文字/fleet/{fleetId}有效的。 這是故意的嗎? 我錯過了一些配置嗎? 或者這不是它的工作原理?

我對 WebSockets 或這個 Spring 項目還不是很熟悉,所以提前致謝。

控制器.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();
    }
}

索引.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
    });
});

發送樣品

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

即使@MessageMapping支持占位符,它們也不會在@SendTo目標中公開/解析。 目前,無法使用@SendTo注釋定義動態目的地(請參閱問題SPR-12170 )。 您可以SimpMessagingTemplate使用SimpMessagingTemplate (無論如何它都是內部工作方式)。 以下是您的操作方法:

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

在您的代碼中,目的地 ' /topic/fleet/{fleetId} ' 被視為文字,這就是訂閱它的原因,因為您發送到完全相同的目的地。

如果您只想發送一些初始用戶特定數據,您可以直接在訂閱中返回它:

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

更新:在 Spring 4.2 中,支持目標變量占位符,現在可以執行以下操作:

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

您可以在路徑內發送一個變量。 例如,我發送“este/es/el/chat/java/ ”並在服務器中獲得“este:es:el:chat:java:

客戶:

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

服務器:

@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("/",":");

實際上,我認為這就是您可能正在尋找的內容:

@Autorwired
lateinit var template: SimpMessageTemplate;

@MessageMapping("/class/{id}")
@Throws(Exception::class)
fun onOffer(@DestinationVariable("id") id: String?, @Payload msg: Message) {
    println("RECEIVED " + id)
    template.convertAndSend("/topic/class/$id", Message("The response"))
}

希望這可以幫助某人! :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM