Question

J'ai une application Spring simple avec une fonctionnalité Websocket et tout fonctionne jusqu'à présent.Maintenant, je souhaite envoyer un message de mon serveur à un client spécifique en utilisant l'annotation @SendToUser.Cela me donne l'erreur "Message ignoré, aucune information principale disponible".Je comprends que je n'ai aucun identifiant sur mon serveur, donc chaque utilisateur est "anonyme" et n'a pas de principal (je n'utilise pas Spring Security pour l'instant).Mais chaque utilisateur a un identifiant de session.N'est-il pas possible d'utiliser l'identifiant de session d'une manière ou d'une autre pour différencier les utilisateurs ?Comment puis-je y parvenir pour que mes utilisateurs obtiennent un principal qui correspond à l'identifiant de session ?

Était-ce utile?

La solution

Je pense qu'une solution peut être d'éviter d'utiliser @SendToUser et d'utiliser RAW SimpMessagingTemplate et d'envoyer des messages à une destination que vous contrôlez pour des sessions ouvertes.

pour par exemple.En supposant que vous ayez eu une identité pour une nouvelle session WebSocket, vous pouvez vous abonner à une file d'attente avec cet identifiant dans le nom de la file d'attente:

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

MAINTENANT, sur le côté STRESTER STOCKETTER, vous pouvez diriger vos réponses à l'aide de 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());
    }
....

Autres conseils

Utiliser @SendToUser et ajoutez "/user/" devant la file d'attente lors de l'abonnement (uniquement côté abonné).Le repos fonctionne par magie :-)

Au lieu de

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

et

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

utiliser:

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

et

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

bâtiment sur Réponse de Biju et à l'aide de l'ID de session généré par piétonnement (merde> (merci, Mariusz2108 Dans sa réponse à une question similaire ), voici ce qui a fonctionné pour moi (basé sur L'exemple canonique du ressort )

Client Springframework:

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

au lieu de l'ID de session de Stomp, vous pouvez utiliser votre identifiant de session de votre conteneur Web (par exemple, JSessionID), mais maintenant que le cookie est non accessible par défaut accessibleDe JavaScript (pour Tomcat), c'est une perspective plus difficile.

Essayez ceci.Cela a fonctionné pour moi

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top