Domanda

Ho una semplice applicazione Spring con funzionalità websocket e finora tutto funziona.Ora voglio inviare un messaggio dal mio server a un client specifico utilizzando l'annotazione @SendToUser.Questo mi dà l'errore "Ignoro messaggio, nessuna informazione principale disponibile".Capisco che non ho alcun accesso sul mio server, quindi ogni utente è "anonimo" e non ha un preside (per ora non sto utilizzando Spring Security).Ma ogni utente ha un ID di sessione.Non è possibile utilizzare l'ID di sessione in qualche modo per distinguere tra gli utenti?Come posso ottenere ciò in modo che i miei utenti ottengano un'entità che corrisponde all'ID sessione?

È stato utile?

Soluzione

Penso che una soluzione potrebbe essere quella di evitare l'uso @SendToUser e usalo crudo SimpMessagingTemplate e per inviare messaggi a una destinazione che controlli per le sessioni aperte.

Per es.presupponendo che tu abbia un'identità per una nuova sessione websocket, puoi iscriverti a una coda con quell'identificatore nel nome della coda:

stomp.subscribe("/queue/chats" + "-" + mycustomidentifier, onmessage);

Ora, sul lato ascoltatore websocket Spring, puoi indirizzare le tue risposte utilizzando SimpMessagingTemplate:

@Controller
public class MyController {


    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/chats")
    public void handleChat(@Payload ChatMessage message) {
        this.simpMessagingTemplate.convertAndSend("/queue/chats-" + "mycustomidentifier", "[" + getTimestamp() + "]:" + message.getMessage());
    }
....

Altri suggerimenti

Utilizzare @SendToUser e aggiungi "/ User /" davanti alla coda durante la sottoscrizione (solo il lato del sottoscrittore).Rest Works Magic: -)

invece di

Java Server: @SendTo("/topic/showResult")
.

e

JS Client: stompClient.subscribe('/topic/showResult', function(calResult){  ....
.

Uso:

Java Server: @SentToUser("/topic/showResult")

e

JS Client: stompClient.subscribe('/user/topic/showResult', function(calResult){ ....

Building on La risposta di Biju e usando il Stomp Generated Session ID (grazie, Mariusz2108 nella sua risposta a una domanda simile ), ecco cosa ha funzionato per me (basato su L'esempio canonico dalla molla )

Primaveraforework client:

private SimpMessagingTemplate template;

@Autowired
public GreetingController(SimpMessagingTemplate template) {
    this.template = template;
}

@MessageMapping("/hello")
public void greeting(HelloMessage message, @Header("simpSessionId") String sessionId) throws Exception {
    template.convertAndSend("/queue/greeting-"+sessionId, new Greeting("Hello, " + message.getName()));
}
.

JavaScript Client:

function connect() {
    var socket = new SockJS('/gs-guide-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        var sessionId = /\/([^\/]+)\/websocket/.exec(socket._transport.url)[1];
        console.log("connected, session id: " + sessionId);
        stompClient.subscribe('/queue/greeting-'+sessionId, function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}
.

Invece dell'ID di Stomp Session è possibile utilizzare il tuo ID sessione del tuo contenitore Web (ad es. JsessionID) ma ora che Cookie è non per impostazione predefinita accessibileDa JavaScript (per Tomcat) Questa è una prospettiva più difficile.

Prova questo.Ha funzionato per me

@Autowired
private SimpMessagingTemplate messagingTemplate;

@MessageMapping("/getHello")
public void sendReply( MessageHeaders messageHeaders, @Payload String message, @Header(name = "simpSessionId") String sessionId){
        messagingTemplate.convertAndSendToUser(sessionId, "/queue/hello", "Hello "+ message, messageHeaders);
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top