Переменные пути в Spring WebSockets @sendto mapping

у меня есть, что я думаю, очень простое приложение Spring WebSocket. Однако я пытаюсь использовать переменные пути для подписки, а также для сопоставления сообщений.

я опубликовал перефразированный пример ниже. Я ожидал бы @SendTo аннотация, чтобы вернуться к подписчикам на основе их fleetId. т. е. POST to /fleet/MyFleet/driver/MyDriver следует уведомить подписчиков /fleet/MyFleet, но я не вижу такого поведения.

стоит отметить, что подписка на литерал /fleet/{fleetId} строительство. Это задумано? Я пропустил какую-то часть конфигурации? Или это просто не так работает?

я еще не очень хорошо знаком с WebSockets или этим весенним проектом, поэтому заранее спасибо.

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

1 ответов


хотя @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));
}

в вашем коде пункт назначения' / тема / флот / {fleetId} ' рассматривается как буквальный, вот почему почему подписка на него работает, просто потому, что вы отправляете в тот же пункт назначения.

если вы просто хотите отправить некоторые исходные данные конкретного пользователя, вы можете вернуть его непосредственно в подписке:

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

обновление: Весной 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);
}