2014-11-20 4 views
27

У меня есть, что я думаю, очень простое приложение Spring WebSocket. Тем не менее, я пытаюсь использовать переменные пути для подписки, а также отображение сообщений.Переменные пути в Spring WebSockets @SendTo mapping

Я разместил приведенный ниже пример. Я бы ожидал, что аннотация @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 
    }); 
}); 

Отправить Sample

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

ответ

63

Даже если @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); 
} 
+0

Спасибо, @sergi! Я надеялся обойтись с помощью MessagingTempalte, но это работает так же хорошо. В чем разница между использованием '@ SubscribeMapping' и' @ SendTo'? Бывшие просто пропускают брокера сообщений? – bvulaj

+2

'@ SubscribeMapping' перехватывает только подписки (а не сообщения на канал), возвращаемое значение будет отправлено непосредственно пользователю, но может быть отменено с помощью' @ SendTo', чтобы отправить его в другой пункт назначения (будет отправлен брокерскому каналу). '@ SendTo' также может использоваться с' @ MessageMapping' для отправки ответа на конкретный пункт назначения.Таким образом, в основном, '@ SendTo' может использоваться вместе с' @ MessageMapping' и '@ SubscribeMapping' –

+0

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

Смежные вопросы