IT

Path variables in Spring WebSockets @SendTo mapping

itgroup 2023. 9. 25. 22:33
반응형

Path variables in Spring WebSockets @SendTo mapping

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.

아래에 의역한 예시를 올렸습니다.저는 기대합니다.@SendTo구독자를 기준으로 다시 돌려주는 주석fleetId. 즉, a.POST로./fleet/MyFleet/driver/MyDriver가입자에게 통지해야 합니다./fleet/MyFleet, 하지만 이런 행동은 보이지 않습니다.

주목할 점은 리터럴을 구독하는 것은/fleet/{fleetId}효과가 있습니다. 이게 의도된 건가요?구성 요소가 누락되어 있습니까?아니면 그냥 이렇게 작동하는게 아닌가요?

I'm not very familiar with WebSockets or this Spring project yet, so thanks in advance.

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

Send Sample

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

그럼에도 불구하고.@MessageMapping자리 표시자를 지원합니다. 그들은 노출/해결되지 않습니다.@SendTo행선지현재 동적 대상을 정의할 수 있는 방법이 없습니다.@SendTo주석(호 SPR-12170 참조).당신은 사용할 수 있습니다.SimpMessagingTemplate당분간은 (어쨌든 내부적으로는 그렇게 작동합니다.)다음과 같은 방법으로 수행할 수 있습니다.

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

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

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! :)

ReferenceURL : https://stackoverflow.com/questions/27047310/path-variables-in-spring-websockets-sendto-mapping

반응형