STOMP

SeungJoo
|2024. 1. 23. 23:53
반응형
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");  // 메시지 브로커를 설정 ("/topic"은 예시)
        config.setApplicationDestinationPrefixes("/app");  // 클라이언트로부터의 메시지를 처리할 엔드포인트 설정
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket-example").withSockJS();  // WebSocket 엔드포인트 설정
    }
}

STOMP

효율적인 메세징 전송을 위해 탄생한 프로토콜로, 클라이언트와 서버 간 메시지의 유형형식, 내용을 WebSocket 위에서 정의하는 프로토콜입니다. Pub/Sub 구조를 기본으로 하며, 이는 메시지 전송과 처리를 명확하게 정의하여 개발자가 이해하고 개발하기 용이합니다. 또한, 헤더에 값을 부여하여 통신 시 인증 처리를 구현할 수 있어 보안적인 측면에서도 강력한 기능을 제공합니다. STOMP 스펙을 준수하면 다양한 언어와 플랫폼 간에 메시지를 상호 운영할 수 있습니다.

STOMP은 양방향 네트워크 프로토콜인 TCP 또는 WebSocket을 기반으로 동작합니다. 이름에서 알 수 있듯이 Text 지향 프로토콜이지만, Message Payload에서는 Text나 Binary 데이터를 포함할 수 있습니다.

Pub/Sub는 메시지를 공급하는 주체와 소비하는 주체를 분리해 제공하는 메시징 방법입니다. 이는 채팅방을 예로 들어 설명할 수 있습니다. 채팅방을 생성하면 채팅방에 입장하는 것은 채팅방에서 메시지를 주고받는 것은 해당 Topic으로 메시지를 송신하거나 수신하는 것과 유사합니다.

클라이언트는 메시지를 전송하기 위해 SEND, SUBSCRIBE COMMAND를 사용하며, 이때 메시지 내용 및 헤더 정보는 해당 명령어의 요청 Frame에 포함됩니다.

STOMP는 Publish-Subscribe 메커니즘을 제공하며, 이를 통해 Broker를 통해 다른 사용자에게 메시지를 보낼 수 있습니다. Spring에서 지원하는 STOMP는 Simple In-Memory Broker를 이용해 SUBSCRIBE 중인 다른 클라이언트에게 메시지를 전송할 수 있습니다. 또한, 외부 메시징 시스템인 RabbitMQ, ActiveMQ 등을 STOMP Broker로 사용할 수도 있습니다. 또한

Spring 구조에서는 메시지를 외부 Broker에게 전달하고, Broker가 WebSoket으로 연결된 클라이언트에게 메시지를 전달하는 방식으로 동작합니다. 이러한 동작 방식으로 이해 HTTP 기반의 보안 설정과 공통된 검증을 적용할 수 있습니다.

spring-messaging 모듈은 Spring 프레임워크에서 통합된 Messaging 애플리케이션을 지원하는 기능을 제공합니다. 이 모듈은 Message, MessageHandler, SimpleAnnotationMethod, SimpleBroker 등의 핵심 개념과 클래스를 포함하고 있습니다.

1. Message
   정의: Headers와 payload를 포함하는 메시지의 표현
   활용: 다양한 메세징 시나리오에서 메시지를 표현하고 전송하는 데 사용

2. MessageHandler
   정의: Message 처리에 대한 계약을 나타내는 인터페이스
   활용: 서버에서 클라이언트로부터 수신한 메시지를 처리하는 역할

3. SimpleAnnotationMethod
   정의: @MessageMapping 등을 통해 클라이언트의 SEND를 받아서 처리하는 클래스
   활용: 어노테이션 기반으로 메서드를 매핑하여 클라이언트로부터의 요청을 처리

4. SimpleBroker
   정의: 클라이언트의 정보를 메모리 상에 유지하며, 클라이언트로 메시지를 전송하는 역할을 하는 클래스
   활용:메모리 기반의 브로커로, 클라이언트 간 메시지 전송을 관리

5. Channels
clientInboundChannel(클라이언트로부터 받은 메시지를 서버로 전달하는 역할)
WebSocket Client로부터 들어오는 요청을 전달하며, WebSocketMessageBrokerConfigurer를 통해 intercept, taskExecutor를 설정할 수 있습니다.

clientOutboundChannel(서버에서 클라이언트로 메시지를 전송하는 역할)
WebSocket Client로 Server의 메시지를 내보내며, WebSocketMessageBrokerConfigurer를 통해 intercept, taskExecutor를 설정할 수 있습니다.

brokerChannel(서버의 애플리케이션 코드 내에서 브로커에게 메시지를 전달하는 역할)
Server 내부에서 사용하는 채널로, SimpleAnnotationMethod은 SimpleBroker의 존재를 직접 알지 못해도 메시지를 전달할 수 있습니다. 

WebSocket Configuration

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");  // 메시지 브로커를 설정 ("/topic"은 예시)
        config.setApplicationDestinationPrefixes("/app");  // 클라이언트로부터의 메시지를 처리할 엔드포인트 설정
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket-example").withSockJS();  // WebSocket 엔드포인트 설정
    }
}

Controller

@Controller
public class ChatController {

    @MessageMapping("/chat.sendMessage")
    @SendTo("/topic/public")
    public ChatMessage sendMessage(@Payload ChatMessage chatMessage) {
        return chatMessage;
    }

    @MessageMapping("/chat.addUser")
    @SendTo("/topic/public")
    public ChatMessage addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor) {
        // 클라이언트에 접속한 사용자를 WebSocket 세션에 추가
        headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
        return chatMessage;
    }
}

Entity

public class ChatMessage {

    private MessageType type;
    private String content;
    private String sender;
    
}
728x90

'Spring(Boot & FrameWork)' 카테고리의 다른 글

CRON 표현식  (0) 2024.02.08
Web Socket  (0) 2024.01.22
지연로딩, 즉시로딩  (0) 2023.12.26