1. STOMP란
- 원래는 스크립트 언어(Ruby, Python, Perl 등)에서 엔터프라이즈 메시지 브로커와 통신할 수 있도록 만들어진 텍스트 기반 메시징 프로토콜.
- TCP, WebSocket 등 신뢰할 수 있는 양방향 스트리밍 프로토콜 위에서 동작 가능.
- 텍스트 지향이지만, Payload(본문) 는 텍스트 또는 바이너리 모두 지원 가능.
구성 요소
| 구성요소 | 설명 |
| Message |
헤더 + 페이로드를 가진 기본 메시지 객체
|
| MessageHandler |
메시지를 처리하는 계약 인터페이스
|
| MessageChannel |
메시지를 송신할 수 있는 인터페이스 (생산자와 소비자 분리)
|
| SubscribableChannel |
메시지를 구독할 수 있는 인터페이스
|
| ExecutorSubscribableChannel |
메시지를 비동기로 처리할 수 있도록 Executor를 사용하는 채널
|
주요 채널
| 채널명 | 방향 | 역할 | 동작 |
| clientInboundChannel |
클라이언트 → 서버
|
클라이언트 메시지 수신, 구독, 라우팅
|
CONNECT, SUBSCRIBE, SEND, @MessageMapping 연결
|
| brokerChannel |
서버 → 브로커
|
애플리케이션 메시지를 브로커로 전달 |
convertAndSend()
|
| clientOutboundChannel | 브로커 → 클라이언트 |
구독자에게 최종 메시지 전송
|
웹소켓 세션 전송
|
2. 메시지 흐름
내장 브로커

- clientInboundChannel: 클라이언트가 보낸 STOMP 메시지를 서버가 수신 (CONNECT, SUBSCRIBE, SEND, DISCONNECTED)
- clientInboundChannel: 클라이언트가 보낸 SUBSCRIBE 요청을 받아 서버 내부에서 토픽별 세션 정보 관리
- clientInboundChannel: 클라이언트가 보낸 SEND 메시지를 @MessageMapping으로 전달
- brokerChannel: @MessageMapping 결과 또는 SimpMessagingTemplate 메시지를 SimpleBroker에 전달
- clientOutboundChannel: SimpleBroker가 구독중인 세션을 찾아 클라이언트에 메시지 전송
외장 브로커

- clientInboundChannel: 클라이언트가 보낸 STOMP 메시지를 서버가 수신 (CONNECT, SUBSCRIBE, SEND, DISCONNECTED)
- clientInboundChannel: 클라이언트가 보낸 SUBSCRIBE 요청을 받아 세션/구독 정보 관리함.
- clientInboundChannel: 클라이언트가 보낸 SEND 메시지를 @MessageMapping으로 전달
- brokerChannel: @MessageMapping 결과 또는 SimpMessagingTemplate 메시지를 broker relay를 통해 외부 브로커로 publish함
- clientOutboundChannel: SimpleBroker가 구독중인 세션을 찾아 클라이언트에 메시지 전송
3. 이점
| 항목 | 설명 | 이점 |
| @Controller를 통한 메시지 핸들링 | @MessageMapping 메소드에 메시지 자동 분배 |
코드 구조가 모듈화되고 깔끔해짐
|
| Spring Security를 통한 보안 설정 | 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별 인증/인가
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 Stomp' 카테고리의 다른 글
| [Spring WebSockets] 2-3. STOMP: 부가 기능 (1) | 2025.05.04 |
|---|---|
| [Spring WebSockets] WebSockets (0) | 2025.05.02 |
| [Stomp] Spring Boot with React 채팅 서버 : 3-2. Stomp 기본 설정 (2) | 2022.03.14 |
| [Stomp] Spring Boot with React 채팅 서버 : 3-1. Stomp 정리 및 설명 (0) | 2022.03.02 |
| [Stomp] Spring Boot with React 채팅 서버 : 2. ChatRoomController (0) | 2022.03.02 |