Back-end/Spring

[Spring Websocket] STOMP - convertAndSendToUser 사용법

 

STOMP란?

 문자 기반의 송수신을 위한 문자 기반 메세징 프로토콜

 

convertAndSendToUser()

채널에 구독하고 있는 사용자들 중 모두에게가 아닌 특정한 사용자에게 메세지를 보낼 수 있도록 해주는 메소드

convertAndSendToUser(String user, String destination, Object payload)

이때 convertAndSend와 같이 두 번째와 세 번째 파라미터에는 채널과 보낼 데이터를 넣어야 하는 것을 알 수 있다.

그러나 처음에 convertAndSendToUser를 사용하면서 첫 번째 파라미터인 user에는 무엇이 들어가야 할지를 알 수 없었다.

 

파라미터

처음에는 username을 입력해주면 되지 않을까 싶었다. 그러나 다시 생각해보니 username은 본인이 직접 만든 것이기 때문에 터무니없는 생각이었다.

 

그래서 인터넷에 검색해본 결과 java.security에서 제공해주는 웹 통신의 주체에 대한 정보가 담겨있는 Principal 객체를 사용하는 것을 알 수 있었다.

 

그리고 이 객체에 사용자의 웹 소켓 세션이 연결되기 전에 UUID를 랜덤 하게 생성해주어 고유한 세션 이름을 생성하는 것을 알 수 있었다.

 

방법

 

1. 웹 소켓 세션 주체의 정보를 담고 있는 java.security.principal 객체를 상속한 StompPrincipal 클래스를 만들자

class StompPrincipal implements Principal {
    String name

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

    @Override
    String getName() { return name;}
}

2. 웹 소켓의 세션이 연결될 때 실행될 수 있는 고유한 UUID를 생성해주는 핸들러를 만들자

class CustomHandshakeHandler extends DefaultHandshakeHandler {
    @Override
    protected Principal determineUser(ServerHttpRequest request,
                                      WebSocketHandler wsHandler,
                                      Map<String, Object> attributes) {
        return new StompPrincipal(UUID.randomUUID().toString());
    }
}

determinUser를 오버라이드해서 랜덤한 UUID를 생성할 수 있도록 해주었다.

 

3. 핸들러를 생성했으니 실행될 수 있게 설정하도록 하자

registry.addEndpoint("/chat").setAllowedOriginPatterns("*").setHandshakeHandler(new CustomHandshakeHandler()).withSockJS();

setHandshakeHandler를 추가시켜주면 된다.

 

4. 마지막으로 제대로 세션의 고유한 ID가 생성되었는지 확인해보자.

 

이때 확인할 수 있는 방법은 2가지가 있다.

첫번째 웹 브라우저에서 세션이 연결되었을 때 세션에 대한 정보들이 나오는 FRAME을 콘솔 창으로 보는 방법

핸들러에서 생성한 후 Shake할때 같이 보내주는 것을 볼 수 있다.

 

두 번째 메세지 매핑을 할 때 Principal 객체를 request로 설정해서 getName()을 통해 해결해주는 방법

이것으로 얻은 세션의 ID를 이용해서 자신이 원하는 특정한 사용자에게 메세지를 보내주도록 해보자!

simpMessageTemplate.convertAndSendToUser(principal.getName(), "topic/chat/", userPacket);

 

반응형