STOMP 구조 및 Spring Websocket Client 구현해보자!

Karim·2023년 4월 17일
5

SpringBoot

목록 보기
12/15
post-thumbnail

1. STOMP 란

  • Simple Text Oriented Messaging Protocol
  • TCP 또는 WebSocket 같은 양방향 네트워크 프로토콜 기반으로 동작
  • Message Payload에는 Text or Binary 데이터를 포함 할 수 있다.
  • pub/sub 구조로 동작

2. Spring WebSocket STOMP

  • Spring에서 지원하는 stomp
  • 메세지 송수신에 대한 처리가 명확하게 정의할 수 있다.
  • WebSocketHandler 를 직업 구현할 필요 없이, @MessagingMapping 어노테이션을 사용해 메시지 발행 시 엔드포인트를 별로도 분리해서 관리할 수 있다.

3. STOMP Frame 구조

💡

  • stomp는 http에서 모델링되는 프레임 기반 프로토콜
COMMAND 
header1:value1 
header2:value2 

Body^@

4. client - server 구독

💻

SUBSCRIBE 
id:sub-1 
destination:/sub/cache/karim

^@

5. Send to Message

💻 client to server

SEND
destination:/pub/cache/karim
content-type:application/json
content-length:44

{"channelId":"karim"}^@

💻 server to client

MESSAGE
message-id:nxahklf6-1
subscription:sub-1
destination:/sub/cache/karim

{"channelId":"karim"}^@

6. STOMP 동작 흐름

💻 stomp 동작 흐름도

7. 시작 전 확인사항

💬 version

IntelliJ : 2022.1.3.Ultimate
spring boot : 2.6.1

💬 gradle 추가

implementation 'org.springframework.boot:spring-boot-starter-websocket'

8. STOMP Client

✒️ ClientWebSocketStompConfig

@Configuration
public class ClientWebSocketStompConfig {

    @Bean
    public WebSocketStompClient WebSocketStompClient(WebSocketStompClient webSocketClient,
                                                     StompSessionHandler stompSessionHandler) {

		// client to server message converter
		webSocketClient.setMessageConverter(new MappingJackson2MessageConverter());

        StompHeaders stompHeaders = new StompHeaders();
        stompHeaders.add("host", "karim");

        Object[] urlVariables = {};
        String url = "wss://localhost:8443/ws";
        webSocketClient.connect(url, null, stompHeaders, stompSessionHandler, urlVariables);

        return webSocketClient;
    }

    @Bean
    public WebSocketStompClient webSocketClient() {
        WebSocketClient webSocketClient = new StandardWebSocketClient();
        return new WebSocketStompClient(webSocketClient);
    }
    @Bean
    public StompSessionHandler stompSessionHandler() {
        return new ClientWebSocketStompSessionHandler();
    }
}

✒️ ClientWebSocketStompSessionHandler

public class ClientWebSocketStompSessionHandler extends StompSessionHandlerAdapter {

    @Override
    public void handleFrame(StompHeaders headers, Object payload) {
        
        // 구독한 채널의 메세지 받기
        System.out.println("SpringStompSessionHandler.handleFrame");
        System.out.println("headers = " + headers);
        System.out.println("payload = " + new String((byte[]) payload));
    }

    @Override
    public Type getPayloadType(StompHeaders headers) {
        return Object.class;
    }

    @Override
    public void afterConnected(StompSession session, StompHeaders connectedHeaders) {

        // 구독
        session.subscribe("/sub/cache/karim", this);

        Map<String, Object> params = new HashMap<>();
        params.put("channelId", "karim");
        // 메세지 보냄
        session.send("/sub/cache/karim", params);

        System.out.println("params = " + params);
    }

    @Override
    public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) {
        System.out.println("SpringStompSessionHandler.handleException");
        System.out.println("exception = " + exception);
    }

    @Override
    public void handleTransportError(StompSession session, Throwable exception) {
        // 이부분 서버 꺼져서 처음에 못붙거나, 붙었다가 서버 꺼지면 나옴 이때 재 커넥션 와일 돌리면 될꺼같음
        System.out.println("SpringStompSessionHandler.handleTransportError");
    }
}

7. STOMP Test 실행화면

💻 server

💻 client


📌 여담

📚 참고

profile
나도 보기 위해 정리해 놓은 벨로그

0개의 댓글