2015-01-21 17 views
5

Sto lavorando con l'implementazione di Websocket di Spring. Per l'invio di un messaggio ai clienti, ci sono due modi:Disallow broadcast nel metodo convertAndSendToUser in SimpMessagingTemplate

1) Utilizzando @SendToUser annotazione
2) Usando convertAndSendToUser metodo SimpMessagingTemplate

@SendToUser prende un parametro booleano chiamato broadcast che, se impostato su false pubblica il messaggio la sessione corrente. C'è un modo per avere questo comportamento in SimpMessagingTemplate.

risposta

4

Se diamo uno sguardo al codice sorgente di SendToMethodReturnValueHandler, vedremo:

if (broadcast) { 
    this.messagingTemplate.convertAndSendToUser(user, destination, returnValue); 
} 
else { 
    this.messagingTemplate.convertAndSendToUser(user, destination, returnValue, createHeaders(sessionId)); 
} 

Allora, che cosa avete bisogno per il vostro caso d'uso solo l'uso che sovraccarica convertAndSendToUser e fornire un Map con `sessionId:

messagingTemplate.convertAndSendToUser(user, destination, payload, 
      Collections.singletonMap(SimpMessageHeaderAccessor.SESSION_ID_HEADER, sessionId)) 
+0

Come posso ottenere 'sessionId' se il mio metodo è annotato con' @RequestMapping() ', in questo metodo, dopo un po 'di lavoro fatto Voglio avvisare gli altri utenti, grazie. –

+0

Per favore, inizia una nuova domanda SO –

+0

per favore dare un'occhiata a [Come iscriversi usando l'integrazione Sping Websocket su userName specifico (userId) + ricevere notifiche dal metodo anotato con @RequestMapping?] (Https://stackoverflow.com/q/ 47628608/3425489) –

1

La risposta sopra non ha funzionato per me. Si scopre che con Spring 4.1.4 è richiesto qualcosa di leggermente diverso.

Il modo che sembra il più pulito che mi appare come il seguente:

SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(); 
headerAccessor.setSessionId(cmd.getSessionId()); 
headerAccessor.setLeaveMutable(true); 
MessageHeaders messageHeaders = headerAccessor.getMessageHeaders(); 

messagingTemplate.convertAndSendToUser(cmd.getPrincipal().getName(), 
     "/queue/responses", ret, messageHeaders); 

L'altro modo che ha funzionato è stato quello di aggiungere in modo esplicito un valore "nativeHeaders" al Map inviato a SimpMessagingTemplate.convertAndSendToUser(). Tuttavia, in questo modo sembra dipendere troppo sui dettagli di implementazione:

Map<String, Object> headers = new HashMap<>(); 
headers.put("nativeHeaders", new HashMap<String, Object>()); 
headers.put(SimpMessageHeaderAccessor.SESSION_ID_HEADER, cmd.getSessionId()); 

messagingTemplate.convertAndSendToUser(cmd.getPrincipal().getName(), 
     "/queue/responses", ret, headers); 

Il "codice incriminato", che ha reso l'impostazione l'intestazione "simpSessionId" e niente altro in una Mappa non lavoro era in SimpMessagingTemplate.processHeaders() e MessageHeaderAccessor .getAccessor (MessageHeaders, Classe requiredType).

+0

Che cosa è 'cmd' nel codice? – mkczyk

1

Spring non ha un documento chiaro, ho provato molti modi diversi, solo sotto il codice funziona per me.

SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.create(); 
accessor.setHeader(SimpMessageHeaderAccessor.SESSION_ID_HEADER, sessionId); 
messagingTemplate.convertAndSendToUser(sessionId, destination, payload, accessor.getMessageHeaders());