Ce que je pense être une application Spring WebSocket très simple. Cependant, j'essaie d'utiliser des variables de chemin d'accès pour l'abonnement ainsi que le mappage des messages.
J'ai posté un exemple paraphrasé ci-dessous. Je m'attendrais à ce que l'annotation @SendTo
soit renvoyée aux abonnés en fonction de leur fleetId
. C'est-à-dire qu'une POST
à /fleet/MyFleet/driver/MyDriver
devrait notifier les abonnés de /fleet/MyFleet
, mais je ne vois pas ce comportement.
Il est intéressant de noter que s’abonner au /fleet/{fleetId}
littéral fonctionne. Est-ce prévu? Est-ce qu'il me manque un morceau de configuration? Ou est-ce simplement pas comment ça marche?
Je ne connais pas encore très bien WebSockets ou ce projet Spring, merci d'avance.
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
});
});
Envoyer un échantillon
stompClient.send("/live/fleet/MyFleet/driver/MyDriver", {}, JSON.stringify({
// Some simple content
}));
Même si @MessageMapping
prend en charge les espaces réservés, ils ne sont pas exposés/résolus dans les destinations @SendTo
. Actuellement, il est impossible de définir des destinations dynamiques avec l'annotation @SendTo
(voir le numéro SPR-12170 ). Vous pouvez utiliser la SimpMessagingTemplate
pour le moment (c'est comme ça que ça fonctionne en interne de toute façon). Voici comment vous le feriez:
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
public void simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
simpMessagingTemplate.convertAndSend("/topic/fleet/" + fleetId, new Simple(fleetId, driverId));
}
Dans votre code, la destination '/topic/flotte/{flotteId}' est traitée comme un littéral, c'est pourquoi son abonnement fonctionne, simplement parce que vous envoyez la même destination.
Si vous souhaitez simplement envoyer des données initiales spécifiques à l'utilisateur, vous pouvez les renvoyer directement dans l'abonnement:
@SubscribeMapping("/fleet/{fleetId}/driver/{driverId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
Update: Dans Spring 4.2, les espaces réservés des variables de destination sont pris en charge. Il est maintenant possible de faire quelque chose comme:
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
vous pouvez envoyer une variable à l'intérieur du chemin. par exemple, je vous envoie "este/es/el/chat/Java /" et vous obtenez le serveur comme "este: es: el: chat: Java: "
client:
stompSession.send("/app/chat/este/es/el/chat/Java/*", ...);
serveur:
@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("/",":");