Pregunta

Tengo una aplicación Spring simple con funcionalidad websocket y todo funciona hasta ahora.Ahora quiero enviar un mensaje desde mi servidor a un cliente específico usando la anotación @SendToUser.Esto me da el error "Ignorando el mensaje, no hay información principal disponible".Entiendo que no tengo ningún tipo de inicio de sesión en mi servidor, por lo que cada usuario es "anónimo" y no tiene un principal (no estoy usando Spring Security por ahora).Pero cada usuario tiene una identificación de sesión.¿No es posible utilizar la identificación de sesión de alguna manera para diferenciar entre usuarios?¿Cómo puedo lograr eso para que mis usuarios obtengan un principal que corresponda al ID de sesión?

¿Fue útil?

Solución

Creo que una solución podría ser evitar el uso @SendToUser y usar crudo SimpMessagingTemplate y enviar mensajes a un destino que usted controle para sesiones abiertas.

Por ej.suponiendo que tenía alguna identidad para una nueva sesión de websocket, puede suscribirse a una cola con ese identificador en el nombre de la cola:

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

Ahora, en el lado del oyente de Spring websocket, puede dirigir sus respuestas usando 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());
    }
....

Otros consejos

Use @SendToUser y agregue "/ usuario /" en frente de la cola cuando se suscribe (solo el lado del suscriptor).Resto Works Magic: -)

en lugar de

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

y

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

Uso:

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

y

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

edificio en la respuesta de Biju y usando la ID de sesión (gracias, mariusz2108 En su respuesta a una pregunta similar ), esto es lo que funcionó para mí (basado en el ejemplo canónico de la primavera )

Cliente de flama de primavera:

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

Client Javascript:

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

En lugar de la ID de sesión de stupt, podría usar la ID de sesión de su contenedor web (por ejemplo, JSessionid), pero ahora que Cookie es no por defecto accesibleDesde JavaScript (para Tomcat), esta es una perspectiva más difícil.

Intenta esto.Funcionó para mí

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top