복붙노트

[SPRING] 로그인하지 않고 스프링 웹 소켓 @SendToUser?

SPRING

로그인하지 않고 스프링 웹 소켓 @SendToUser?

나는 websocket 기능을 가진 간단한 스프링 애플리케이션을 가지고 있고 모든 것이 지금까지 작동한다. 이제 @SendToUser 주석을 사용하여 서버에서 특정 클라이언트로 메시지를 보내려고합니다. 이 메시지는 "메시지 무시, 사용 가능한 주요 정보 없음"오류입니다. 내 서버에는 로그인이 전혀 없으므로 모든 사용자가 "익명"이며 교장이 없다는 것을 이해합니다 (현재 스프링 보안을 사용하지 않습니다). 그러나 모든 사용자는 세션 ID를가집니다. 어떻게 세션 ID를 사용하여 사용자를 구분할 수 있습니까? 어떻게하면 내 사용자가 세션 ID에 해당하는 주체를 얻을 수 있습니까?

해결법

  1. ==============================

    1.해결책은 @SendToUser를 사용하지 않고 원시 SimpMessagingTemplate을 사용하고 열린 세션에 대해 제어하는 ​​대상에 메시지를 보내는 것일 수 있습니다.

    해결책은 @SendToUser를 사용하지 않고 원시 SimpMessagingTemplate을 사용하고 열린 세션에 대해 제어하는 ​​대상에 메시지를 보내는 것일 수 있습니다.

    예를 들면. 새로운 websocket 세션에 대한 신원이 있다고 가정하면 큐 이름에 해당 식별자가있는 대기열에 가입 할 수 있습니다.

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

    이제 Spring 웹 소켓 리스너 측면에서 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());
        }
    ....
    
  2. ==============================

    2.@SendToUser를 사용하고 구독 할 때 대기열 앞에 "/ user /"를 추가하십시오 (구독자 측만). 나머지 마술은 :-)

    @SendToUser를 사용하고 구독 할 때 대기열 앞에 "/ user /"를 추가하십시오 (구독자 측만). 나머지 마술은 :-)

    대신에

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

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

    용도:

    자바 서버 : @SentToUser ( "/ topic / showResult")

    JS 클라이언트 : stompClient.subscribe ( '/ user / topic / showResult', function (calResult) {....

  3. ==============================

    3.Biju의 답을 바탕으로 Stomp에서 생성 한 세션 ID (비슷한 질문에 대한 답은 mariusz2108입니다.)는 다음과 같습니다 (스프링의 표준 예제를 기반으로)

    Biju의 답을 바탕으로 Stomp에서 생성 한 세션 ID (비슷한 질문에 대한 답은 mariusz2108입니다.)는 다음과 같습니다 (스프링의 표준 예제를 기반으로)

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

    자바 스크립트 클라이언트 :

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

    Stomp 세션 ID 대신 웹 컨테이너의 세션 ID (예 : JSESSIONID)를 사용할 수 있지만 쿠키가 기본적으로 자바 스크립트 (Tomcat의 경우)에서 액세스 할 수있는 것은 아니기 때문에 더 어려운 전망입니다.

  4. ==============================

    4.이 시도. 그것은 나를 위해 일했다.

    이 시도. 그것은 나를 위해 일했다.

    @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);
    }
    
  5. from https://stackoverflow.com/questions/25082148/spring-websockets-sendtouser-without-login by cc-by-sa and MIT license