Переменные пути в Spring Отображение WebSockets @SendTo
У меня есть, что я думаю, очень простое приложение Spring WebSocket. Тем не менее, я пытаюсь использовать переменные пути для подписки, а также отображение сообщений.
Я опубликовал приведенный ниже пример. Я ожидаю, что аннотация @SendTo
вернется к подписчикам на основе их fleetId
. т.е. от POST
до /fleet/MyFleet/driver/MyDriver
следует уведомлять подписчиков /fleet/MyFleet
, но я не вижу этого поведения.
Стоит отметить, что работает подписка на литерал /fleet/{fleetId}
. Это предназначено? Не хватает ли какой-то части конфигурации? Или это не так, как это работает?
Я еще не очень хорошо знаком с WebSockets или этим проектом Spring, поэтому заранее спасибо.
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
});
});
Отправить образец
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);
}
Update:
В 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);
}