Spring Websockets @SendToUser without login?

后端 未结 4 1771
梦毁少年i
梦毁少年i 2020-12-09 04:52

I have a simple spring application with websocket functionality and everything works so far. Now I want to send a message from my server to a specific client using the @Send

相关标签:
4条回答
  • 2020-12-09 05:16

    Building on Biju's answer and using the Stomp generated session id (thanks, mariusz2108 in his answer to a similar question), here's what worked for me (based on the canonical example from Spring)

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

    Instead of the Stomp session id you could use your web container's Session ID (e.g. JSESSIONID) but now that cookie is not by default accessible from JavaScript (for Tomcat) this is a more difficult prospect.

    0 讨论(0)
  • 2020-12-09 05:17

    Try this. It worked for 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);
    }
    
    0 讨论(0)
  • 2020-12-09 05:28

    Use @SendToUser and add "/user/" in front of queue when subscribing (only subscriber side). Rest works magic :-)

    Instead of

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

    and

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

    use:

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

    and

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

    0 讨论(0)
  • 2020-12-09 05:41

    I think a solution might be to avoid using @SendToUser and use raw SimpMessagingTemplate and to send messages to a destination that you control for open sessions.

    For eg. assuming that you had some identity for a new websocket session, you can subscribe to a queue with that identifier in the queue name:

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

    Now, on the Spring websocket listener side, you can direct your responses using 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());
        }
    ....
    
    0 讨论(0)
提交回复
热议问题