Stomp 정리
WebSocketMessageBrokerConfigure를 구현한 StompWebsocketConfig 클래스 생성
WebSocketMessageBrokerConfigurer는 STOMP 프로토콜을 기반으로 WebSocket 메시지 브로커를 설정하고 구성할 때 사용
주요 기능
최초 연결을 맺기 위한 endpoint를 정의
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 클라이언트가 "/ws-stomp" 경로로 WebSocket 연결을 시작하도록 설정
registry.addEndpoint("/ws-stomp")
// WebSocket을 지원하지 않는 브라우저를 위해 SockJS 폴백 옵션 활성화
.withSockJS();
}
MessageBrokerRegistry를 통해 메시지를 발행
서버에서 클라이언트로 보내는 메시지는 이 경로를, 클라이언트에서 서버로 보내는 메시지는 특정 경로를 사용하세요 와 같은 우편 분류
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 1. 서버 -> 클라이언트 메시지 전송 (구독)
// "/sub"으로 시작하는 경로를 구독하는 클라이언트에게 메시지를 브로드캐스팅
registry.enableSimpleBroker("/sub");
// 2. 클라이언트 -> 서버 메시지 전송 (발행)
// "/pub"으로 시작하는 경로로 들어온 메시지는 @MessageMapping이 붙은 메서드로 라우팅
registry.setApplicationDestinationPrefixes("/pub");
}
interceptor가 필요하다만 interceptor 클래스 추가
ChanneInterceptor를 구현한 StompHandler 클래스 생성
클라이언트가 서버로 전송하는 STOMP 메시지를 가로채는 인터셉터
위 그림의 메시지 교환 절차 (/app(publish), /topic(subscribe)
클라이언트에서 지정된 /app(publish)/{roomId} 경로로 메시지를 발행하면 broker에 의해서 /topic/{roomId} 이라는 경로의 채널에 메시지가 전달
동시에 /topic/{roomId}를 구독하고 있는 클라이언트에게 실시간으로 메시지가 전달
따라서 해당 roomId에 들어가있는 본인포함1,2,3,4 등 각 유저들에게 메시지를 보낼 수 있는 것이다.
SimpleBroker(브로커) Spring에서 제공하는 메모리 기반 브로커로서, 경로에 따라 메시 지를 분배하고 클라이언트에게 메시지를 전달
@DestinationVariable
어노테이션은 오직 STOMP 메시지를 처리하는 @MessageMapping
메서드에서만 파라미터를 추출하는 용도로 사용할 수 있다는 의미입니다.
Spring MVC의 @RestController
에서 URL 경로의 일부를 추출할 때 @PathVariable
을 사용하는 것처럼, @MessageMapping
에서는 STOMP 메시지의 **목적지 경로(destination path)**에서 변수를 추출할 때 @DestinationVariable
을 사용합니다.
## HTTP의 @PathVariable
vs STOMP의 @DestinationVariable
@PathVariable
vs STOMP의 @DestinationVariable
두 어노테이션은 역할은 비슷하지만, 동작하는 프로토콜과 컨텍스트가 완전히 다릅니다.
구분
@PathVariable
(HTTP)
@DestinationVariable
(WebSocket/STOMP)
사용 위치
@RestController
/ @Controller
@Controller
(STOMP 메시지 처리용)
짝꿍 어노테이션
@GetMapping
, @PostMapping
등
@MessageMapping
경로 예시
/api/rooms/{roomId}
/pub/chat/room/{roomId}
데이터 소스
HTTP 요청의 URL 경로
STOMP 메시지의 'destination' 헤더
@MessageMapping("/{roomId}")
public void sendMessage(@DestinationVariable Long roomId, ChatMessageReqDto chatMessageReqDto) {
System.out.println(chatMessageReqDto.getMessage());
messageSendingOperations.convertAndSend("/topic/" + roomId, chatMessageReqDto);
}
Last updated