Spring/Spring

[Spring WebSockets] 2-1. STOMP: 주요 내용

noahkim_ 2025. 5. 3. 18:56

1. STOMP란

  • 원래는 스크립트 언어(Ruby, Python, Perl 등)에서 엔터프라이즈 메시지 브로커와 통신할 수 있도록 만들어진 텍스트 기반 메시징 프로토콜.
  • TCP, WebSocket신뢰할 수 있는 양방향 스트리밍 프로토콜 위에서 동작 가능.
  • 텍스트 지향이지만, Payload(본문)텍스트 또는 바이너리 모두 지원 가능.

 

2. 이점

항목 설명 이점
@Controller를 통한 메시지 핸들링 @MessageMapping 메소드에 메시지 자동 분배
(STOMP destination 기준)
- WebSocketHandler 하나로 모든 메시지 처리 X
- 코드 구조가 모듈화되고 깔끔해짐
Spring Security를 통한 보안 설정 인증,권한 제어 가능
(STOMP destination + 메시지 타입 기준)
- Destination별 접근 제어 가능
- 메시지 기반으로 권한별 분리된 보안 적용 가능

 

예시) @Controller를 통한 메시지 핸들링 가능

더보기
@Controller
public class ChatController {

    // 클라이언트가 "/app/chat.send"로 메시지를 보내면 이 메소드가 호출됨
    @MessageMapping("/chat.send")
    @SendTo("/topic/public")
    public ChatMessage sendMessage(ChatMessage message) {
        // 받은 메시지를 가공해서 다시 "/topic/public"으로 브로드캐스트
        return message;
    }
}

 

예시) Spring Security로 메시지 보안 설정 가능

더보기
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(ChannelRegistration registration) {
        registration.interceptors(new AuthChannelInterceptorAdapter());
    }

    @Override
    protected boolean sameOriginDisabled() {
        return true; // CORS 정책 예외 (필요에 따라)
    }
}
  • STOMP 메시지가 들어오는 채널을 감시

 

@Configuration
@EnableWebSocketSecurity
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages
            .simpDestMatchers("/app/chat/**").authenticated()  // ① "/app/chat/**"로 가는 메시지는 인증 필요
            .simpDestMatchers("/admin/**").hasRole("ADMIN")    // ② "/admin/**"로 가는 메시지는 ADMIN 권한 필요
            .anyMessage().permitAll();                         // ③ 나머지는 모두 허용
    }
}
  • Destination별 인증/인가

 

3. 메시지 흐름

구성 요소

구성요소 설명
Message
헤더 + 페이로드를 가진 기본 메시지 표현
MessageHandler
메시지를 처리하는 계약 인터페이스
MessageChannel
메시지를 송신할 수 있는 인터페이스 (생산자와 소비자 분리)
SubscribableChannel
메시지를 구독할 수 있는 채널
ExecutorSubscribableChannel
메시지를 비동기로 처리할 수 있도록 Executor를 사용하는 채널

 

메시지 흐름

내장 브로커

내장 브로커

채널명 역할 설명
clientInboundChannel 메시지 처리 (클라이언트 → 서버) 구독 (서버: 토픽 별 세션 정보 관리)
라우팅 (SEND 메시지 🔗 @MessageMapping)
brokerChannel 메시지 전달 (@MessageMapping → SimpleBroker) 메시지 Publish
clientOutboundChannel
메시지 전송 (SimpleBroker → 클라이언트)
브로드캐스팅 (SEND 메시지 ➡️ Subscriber )
- 서버 내의 토픽 별 세션으로 Subscriber 확인

 

외장 브로커

외장 브로커

채널명 역할 설명
clientInboundChannel 메시지 처리 (클라이언트 → 서버) 구독 (서버 ➡️ 외부 브로커, 서버: 토픽 별 세션 정보 관리)
라우팅 (SEND 메시지 🔗 @MessageMapping)
brokerChannel 메시지 전달 (@MessageMapping → 외장 브로커)
- broker relay를 통해 통신
메시지 Publish
clientOutboundChannel 메시지 전송 (외장 브로커 → 서버 → 클라이언트)
- broker relay를 통해 통신
리스닝 (SEND 메시지 -> 벤더별 리스너 애노테이션)
브로드캐스팅 (SEND 메시지 ➡️ Subscriber)
- 서버 내의 토픽 별 세션으로 Subscriber 확인

 

4. 핸들링 어노테이션

어노테이션 역할 비고
@MessageMapping 클라이언트의 SEND 메시지를 특정 메서드로 연결
HTTP의 @RequestMapping와 유사
@SendTo 메서드 결과를 특정 topic으로 브로드캐스팅
구독중인 모든 사용자에게 전송
@SendToUser 메서드 결과를 특정 사용자에게 전송 /user/로 라우팅됨
@SubscribeMapping 클라이언트의 SUBSCRIBE 메시지를 특정 메서드와 연결
구독 직후 초기 데이터
@MessageExceptionHandler @MessageMapping 메서드 실행 중 예외 처리
사용자별 에러 전송 가능

 

예제) @MessageMapping

더보기
@MessageMapping("/chat")
public void handleChatMessage(Message message) {
    // 클라이언트가 /app/chat 으로 보내는 메시지를 처리
}

 

예제) @SendTo

더보기
@MessageMapping("/chat")
@SendTo("/topic/messages")
public Message send(Message message) {
    return message;
}

 

예제) @SendToUser

더보기
@MessageMapping("/private-message")
@SendToUser("/queue/reply")
public Message sendPrivate(Message message) {
    return message;
}

 

예제) @SubscribeMapping

더보기
@SubscribeMapping("/initial-data")
public InitialData sendInitialData() {
    return new InitialData();
}

 

예제) @MessageExceptionHandler

더보기
@MessageExceptionHandler
@SendToUser("/queue/errors")
public String handleException(Throwable exception) {
    return exception.getMessage();
}

 

 

출처

 

'Spring > Spring' 카테고리의 다른 글

[Spring WebSockets] 2-3. STOMP: 부가 기능  (1) 2025.05.04
[Spring WebSockets] WebSockets  (0) 2025.05.02
[Spring][AOP] 3. Advisor API  (0) 2025.04.09
[Spring][AOP] 2. Pointcut API  (1) 2025.04.09
[Spring][AOP] 1. Advice API  (0) 2025.04.09