복붙노트

[SPRING] convertAndSendToUser에서 "user"가 나오는 곳은 SockJS + Spring Websocket에서 작동합니까?

SPRING

convertAndSendToUser에서 "user"가 나오는 곳은 SockJS + Spring Websocket에서 작동합니까?

convertAndSendToUser가 Spring SockJS + Websocket 프레임 워크에서 어떻게 작동하는지 알고 싶습니다.

클라이언트에서 우리는

stompClient.connect(login, password, callback())

그러면 로그인 및 암호의 "Stomp 자격 증명"으로 연결 요청이 발생합니다. 우리가 SessionConnectEvent를 처리한다면 http://www.sergialmar.com/2014/03/detect-websocket-connects-and-disconnects-in-spring-4/

그러나 이것이 서버 측에서 대기열로 작업을 보내는 "사용자"가 될지 여부는 아직 명확하지 않습니다.

 simpMessagingTemplate.convertAndSendToUser(username, "/queue/reply", message);

내가 얻을 수있는 가장 가까운 것은이 스레드를 읽는 것입니다. Spring Websocket의 특정 사용자에게 Thanh Nguyen Van의 대답으로 메시지를 보냅니다. 그러나 여전히 명확하지 않습니다.

기본적으로 내가해야 할 일은 동일한 주제에 대해 일부 클라이언트를 구독하는 것이지만 서버에서는 다른 데이터를 보내야합니다. 클라이언트는 사용자 식별자를 제공 할 수 있습니다.

해결법

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

    1.나는 웹 소켓을 이해하려고 애써 왔고이 질문을 보았습니다. 대답을 찾지 않으려 고 철저히 실망했다. 미래의 독자를위한 무언가가 있습니다.

    나는 웹 소켓을 이해하려고 애써 왔고이 질문을 보았습니다. 대답을 찾지 않으려 고 철저히 실망했다. 미래의 독자를위한 무언가가 있습니다.

    독자가 Stomp를 사용하여 스프링 웹 소켓에 대한 기본적인 지식을 가지고 있다고 가정합니다. 구독, 대상 접두사, 주제, 소켓 구성 파일 등의 용어를 이해합니다.

    예를 들어 구독하는 주제 접두어를 사용하여 스톰 서버에서 클라이언트에게 메시지를 보낼 수 있습니다. / topic / hello. 또한 spring은 convertAndSendToUser (username, destination, message) API를 제공하기 때문에 특정 사용자에게 메시지를 보낼 수 있다는 것도 알고있다. String 사용자 이름을 사용합니다. 즉, 모든 연결에 대해 고유 한 사용자 이름을 사용하면 항목에 가입 한 특정 사용자에게 메시지를 보낼 수 있습니다.

    덜 이해되는 점은이 사용자 이름은 어디에서 유래 했습니까?

    이 사용자 이름은 java.security.Principal 인터페이스의 일부입니다. 각 StompHeaderAccessor 또는 WebSocketSession 객체에는이 보안 주체의 인스턴스가 있으며이 인스턴스에서 사용자 이름을 가져올 수 있습니다. 그러나, 내 실험에 따라, 그것은 자동으로 생성되지 않습니다. 모든 세션에 대해 서버가 수동으로 생성해야합니다.

    이 인터페이스를 사용하려면 먼저이 인터페이스를 구현해야합니다.

    class StompPrincipal implements Principal {
        String name
    
        StompPrincipal(String name) {
            this.name = name
        }
    
        @Override
        String getName() {
            return name
        }
    }
    

    그런 다음 DefaultHandshakeHandler를 재정 의하여 모든 연결에 대해 고유 한 StompPrincipal을 생성 할 수 있습니다. 모든 논리를 사용하여 사용자 이름을 생성 할 수 있습니다. 다음은 UUID를 사용하는 잠재적 인 논리입니다.

    class CustomHandshakeHandler extends DefaultHandshakeHandler {
        // Custom class for storing principal
        @Override
        protected Principal determineUser(ServerHttpRequest request,
                                          WebSocketHandler wsHandler,
                                          Map<String, Object> attributes) {
            // Generate principal with UUID as name
            return new StompPrincipal(UUID.randomUUID().toString())
        }
    }
    

    마지막으로 사용자 정의 핸드 셰이크 핸들러를 사용하도록 웹 소켓을 구성해야합니다.

    @Override
    void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        stompEndpointRegistry
             .addEndpoint("/stomp") // Set websocket endpoint to connect to
             .setHandshakeHandler(new CustomHandshakeHandler()) // Set custom handshake handler
             .withSockJS() // Add Sock JS support
    }
    

    그게 다야. 이제 서버는 모든 연결에 대해 고유 한 주체 이름을 생성하도록 구성됩니다. 연결 이벤트 리스너, MessageMapping 함수 등을 통해 액세스 할 수있는 StomHeaderAccessor 객체의 일부로 해당 보안 주체를 전달합니다.

    이벤트 리스너에서 :

    @EventListener
    void handleSessionConnectedEvent(SessionConnectedEvent event) {
        // Get Accessor
        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage())
    }
    

    메시지 매핑 API에서

    @MessageMapping('/hello')
    protected void hello(SimpMessageHeaderAccessor sha, Map message) {
        // sha available in params
    }
    

    convertAndSendToUser (...) 사용에 대한 마지막 참고. 사용자에게 메시지를 보낼 때 다음과 같은 것을 사용합니다.

    convertAndSendToUser(sha.session.principal.name, '/topic/hello', message)
    

    그러나 클라이언트를 구독하려면

    client.subscribe('/user/topic/hello', callback)
    

    / topic / hello에 클라이언트를 등록하면 브로드 캐스트 메시지 만 수신합니다.

  2. ==============================

    2.나는 어떤 특별한 설정도하지 않았고 나는 이것을 할 수있다.

    나는 어떤 특별한 설정도하지 않았고 나는 이것을 할 수있다.

    @MessageMapping('/hello')
    protected void hello(Principal principal, Map message) {
        String username = principal.getName();
    }
    
  3. from https://stackoverflow.com/questions/37853727/where-user-comes-from-in-convertandsendtouser-works-in-sockjsspring-websocket by cc-by-sa and MIT license