[SPRING] convertAndSendToUser에서 "user"가 나오는 곳은 SockJS + Spring Websocket에서 작동합니까?
SPRINGconvertAndSendToUser에서 "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.나는 웹 소켓을 이해하려고 애써 왔고이 질문을 보았습니다. 대답을 찾지 않으려 고 철저히 실망했다. 미래의 독자를위한 무언가가 있습니다.
나는 웹 소켓을 이해하려고 애써 왔고이 질문을 보았습니다. 대답을 찾지 않으려 고 철저히 실망했다. 미래의 독자를위한 무언가가 있습니다.
독자가 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.나는 어떤 특별한 설정도하지 않았고 나는 이것을 할 수있다.
나는 어떤 특별한 설정도하지 않았고 나는 이것을 할 수있다.
@MessageMapping('/hello') protected void hello(Principal principal, Map message) { String username = principal.getName(); }
from https://stackoverflow.com/questions/37853727/where-user-comes-from-in-convertandsendtouser-works-in-sockjsspring-websocket by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄에 시작할 때 @Cache를로드하는 방법? (0) | 2019.01.02 |
---|---|
[SPRING] 스프링 MVC 스프링 보안과 에러 처리 (0) | 2019.01.02 |
[SPRING] Spring MessageSource는 다중 클래스 경로를 지원합니까? (0) | 2019.01.02 |
[SPRING] 읽을 수있는 로그를 갖기 위해 Spring 로그를 사용 불가능하게한다. (0) | 2019.01.01 |
[SPRING] @Transactional의 이상한 동작 (propagation = Propagation.REQUIRES_NEW) (0) | 2019.01.01 |