2014-11-20 6 views
27

Ho, cosa penso, un'applicazione Spring WebSocket molto semplice. Tuttavia, sto cercando di utilizzare variabili di percorso per la sottoscrizione e la mappatura dei messaggi.Variabili di percorso nel mapping Spring WebSockets @SendTo

Ho pubblicato un esempio parafrasato di seguito. Mi aspetto che l'annotazione @SendTo torni agli abbonati in base al loro fleetId. vale a dire, un POST a /fleet/MyFleet/driver/MyDriver dovrebbe informare gli abbonati di /fleet/MyFleet, ma non vedo questo comportamento.

Vale la pena notare che l'iscrizione a letterale /fleet/{fleetId} funziona. È questo? Mi manca qualche pezzo di configurazione? O semplicemente non funziona così?

Non ho ancora molta familiarità con WebSockets o questo progetto Spring, quindi grazie in anticipo.

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

Invia Esempio

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

risposta

63

Anche se @MessageMapping supporta segnaposto, non sono esposti/risolto in @SendTo destinazioni. Al momento, non è possibile definire le destinazioni dinamiche con l'annotazione @SendTo (vedere il numero SPR-12170). Potresti usare lo SimpMessagingTemplate per il momento (è così che funziona comunque internamente). Ecco come si dovrebbe fare:

@MessageMapping("/fleet/{fleetId}/driver/{driverId}") 
public void simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) { 
    simpMessagingTemplate.convertAndSend("/topic/fleet/" + fleetId, new Simple(fleetId, driverId)); 
} 

Nel codice, la meta '/argomento/flotta/{fleetId}' viene trattato come un letterale, che è il motivo per cui la sottoscrizione di funziona, solo perché si stanno mandando alla stessa identica destinazione.

Se si desidera inviare alcuni dati specifici dell'utente iniziale, si potrebbe restituirlo direttamente nella sottoscrizione:

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

Aggiornamento: In Primavera 4.2, destinazione segnaposto variabili sono supportati è ora possibile fare qualcosa come:

@MessageMapping("/fleet/{fleetId}/driver/{driverId}") 
@SendTo("/topic/fleet/{fleetId}") 
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) { 
    return new Simple(fleetId, driverId); 
} 
+0

Grazie, @sergi! Speravo di andare in giro usando MessagingTempalte, ma funziona altrettanto bene. Qual è la differenza tra l'uso di '@ SubscribeMapping' e' @ SendTo'? Il primo salta semplicemente il broker dei messaggi? – bvulaj

+2

'@ SubscribeMapping' intercetta solo abbonamenti (non messaggi al canale), il valore di ritorno verrà inviato direttamente all'utente, ma può essere sovrascritto con' @ SendTo' per inviarlo a un'altra destinazione (verrà inoltrato al brokerChannel). '@ SendTo' può anche essere utilizzato con' @ MessageMapping' per inviare la risposta a una destinazione specifica.Quindi, in pratica, '@ SendTo' può essere usato insieme a' @ MessageMapping' e '@ SubscribeMapping' –

+0

io devo fare lo stesso project equals, ma non posso iniziare, lo stesso che il prototipo project può usare, in github per esempio. Io so lavoro Spring ma non lavoro WebSocket, ho bisogno di inviare un messaggio a due persone e, il messaggio è uguale a Skype. uno a uno, albero se invito più comunicazioni di un utente –

Problemi correlati