programing

sockJS+Spring 웹소켓에서 "user"가 convertAndSendToUser에서 작동하는 곳은 어디입니까?

muds 2023. 8. 14. 23:10
반응형

sockJS+Spring 웹소켓에서 "user"가 convertAndSendToUser에서 작동하는 곳은 어디입니까?

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

클라이언트에서 다음과 같이 연결합니다.

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

로그인 및 암호의 "Stop credentials"가 포함된 연결 요청이 발생합니다. 예를 들어 SessionConnectEvent http://www.sergialmar.com/2014/03/detect-websocket-connects-and-disconnects-in-spring-4/ 를 처리하는 경우 볼 수 있습니다.

그러나 이것이 서버 측 대기열 전송 작업에서 의미하는 "사용자"가 될지는 여전히 불분명합니다.

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

내가 얻을 수 있는 가장 가까운 것은 이 스레드를 읽는 입니다. Spring 소켓에서 특정 사용자에게 메시지를 보내고 Thanh Nguyen Van이 답변하지만, 여전히 불분명합니다.

기본적으로 제가 해야 할 일은 몇몇 고객들을 같은 주제에 가입시키는 것이지만, 서버에서는 다른 데이터를 그들에게 보내는 것입니다.클라이언트가 사용자 식별자를 제공할 수 있습니다.

예를 들어, 고객이 구독하고 있는 주제 접두사를 사용하여 stopp 서버에서 클라이언트에게 메시지를 보낼 수 있습니다./topic/hello우리는 또한 봄이 특정한 사용자에게 메시지를 보낼 수 있다는 것을 알고 있습니다. 왜냐하면 봄이 제공하기 때문입니다.convertAndSendToUser(username, destination, message)API. String 사용자 이름을 수락합니다. 즉, 모든 연결에 대해 고유한 사용자 이름을 가진 경우 주제에 등록된 특정 사용자에게 메시지를 보낼 수 있어야 합니다.

이해가 덜 된 것은, 이 사용자 이름이 어디에서 왔는가 하는 것입니다.

이 사용자 이름은 인터페이스의 일부입니다.각각StompHeaderAccessor또는WebSocketSession개체에 이 주체의 인스턴스가 있으며 이 주체에서 사용자 이름을 가져올 수 있습니다.하지만, 제 실험에 따르면, 그것은 자동으로 생성되지 않습니다.모든 세션에 대해 서버에서 수동으로 생성해야 합니다.

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

class StompPrincipal implements Principal {
    String name

    StompPrincipal(String name) {
        this.name = name
    }

    @Override
    String getName() {
        return name
    }
}

그러면 고유한 정보를 생성할 수 있습니다.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
}

바로 그겁니다.이제 서버가 모든 연결에 대해 고유한 사용자 이름을 생성하도록 구성되었습니다.그것은 그 교장선생님을 의 일부로 통과시킬 것입니다.StompHeaderAccessor연결 이벤트 수신기, 메시지 매핑 기능 등을 통해 액세스할 수 있는 개체...

이벤트 수신기에서:

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

▁▁using를 사용하는 것에 마지막 참고 .convertAndSendToUser(...)는 다음과 합니다.

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

그러나 클라이언트를 구독하려면 다음을 사용합니다.

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

을 클이언트구경우는에 ./topic/hello브로드캐스트된 메시지만 수신합니다.

특정 구성을 수행하지 않았으며 다음과 같이 수행할 수 있습니다.

@MessageMapping('/hello')
protected void hello(Principal principal, Map message) {
    String username = principal.getName();
}

Wenneguen과 비슷하게 저는 주사를 놓는 것만으로 할 수 있었습니다.Principal에 시대에MessageMapping방법

public void processMessageFromClient(@Payload String message, Principal principal) {

그자리의 principal.getName()은 구현출에서 제공됩니다.org.springframework.security.authentication.UsernamePasswordAuthenticationToken 시간

언급URL : https://stackoverflow.com/questions/37853727/where-user-comes-from-in-convertandsendtouser-works-in-sockjsspring-websocket

반응형