Path variables in Spring WebSockets @SendTo mapping

前端 未结 3 1990
暖寄归人
暖寄归人 2020-12-02 10:02

I have, what I think to be, a very simple Spring WebSocket application. However, I\'m trying to use path variables for the subscription as well as the message mapping.

相关标签:
3条回答
  • 2020-12-02 10:23

    you can send a variable inside the path. for example i send "este/es/el/chat/java/" and obtaned in the server as "este:es:el:chat:java:"

    client:

    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 讨论(0)
  • 2020-12-02 10:34

    Even though @MessageMapping supports placeholders, they are not exposed / resolved in @SendTo destinations. Currently, there's no way to define dynamic destinations with the @SendTo annotation (see issue SPR-12170). You could use the SimpMessagingTemplate for the time being (that's how it works internally anyway). Here's how you would do it:

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

    In your code, the destination '/topic/fleet/{fleetId}' is treated as a literal, that's the reason why subscribing to it works, just because you are sending to the exact same destination.

    If you just want to send some initial user specific data, you could return it directly in the subscription:

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

    Update: In Spring 4.2, destination variable placeholders are supported it's now possible to do something like:

    @MessageMapping("/fleet/{fleetId}/driver/{driverId}")
    @SendTo("/topic/fleet/{fleetId}")
    public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
        return new Simple(fleetId, driverId);
    }
    
    0 讨论(0)
  • 2020-12-02 10:35

    Actually I think this is what you might be looking for:

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

    Hope this helps someone! :)

    0 讨论(0)
提交回复
热议问题