반응형
STMOP란
- Simple Text Oriented Messaing Protocol의 약자
- WebSocket 위에서 동작하는 텍스트 기반 메시징 프로토콜
- 클라이언트와 서버가 전송할 메시지 유형, 형식, 내용들을 정의하는 메커니즘
기본적으로 Publish-Subscribe 구조로 되어있다.
Publish-Subscribe 구조란 **메시지를 공급하는 주체와 소비하는 주체를 분리**해 제공하는 메시징 방법이다.
Springboot에서 STOMP
WebSocket 기반으로 각 Connection마다 WebSocketHandler를 구현하지 않고 @Controller로 된 객체를 이용해 관리할 수 있음
- 메시지는 STOMP의 Destination 헤더를 기반으로 @Controller 객체의 @MethodMapping 메서드로 라우팅 됩니다.
Frame이란
STOMP는 HTTP 위에서 동작하는 Frame 기반 프로토콜
COMMAND
header1:value1
header2:value2
Body^@
- COMMAND: 메시지의 타입을 나타내는 문자열 (send, subscribe, unsubscribe)
- header1, header2: 추가 정보를 제공하는 헤더
- destination: 해당 헤더로 메시지를 보내거나 구독할 수 있음
- Body: 메시지의 내용
- Frame: 통신상 가장 작은 단위
- Message: 다수의 Frame으로 이루어진 구조
- Stream: 클라이언트-서버 간 맺어진 연결을 통해 주고받는 여러 개의 Message
Destination 종류
/topic (Broadcast)
- /topic은 STOMP 클라이언트에서 가장 일반적으로 사용되는 목적지 유형이다. (/topic/<name> 형식)
- 구독자 패턴에 대한 토픽 매칭을 수행하며, 메시지를 여러 구독자에게 라우팅 할 수 있다.
- One-To-Many의 pub-sub 관계
/queue (Unicast)
- /queue는 간단한 대기열을 처리하기 위해 사용됩니다. (/queue/<name>)
- 큐 목적지는 각 메시지를 최대 한 명의 구독자에게 전달하며, 구독자가 없으면 구독자가 큐에 연결할 때까지 큐에 대기합니다.
- One-To-One의 message 교환 관계
Message Broker
- Publisher로부터 전달받은 메시지를 Subscriber에게 메시지를 주고받게 해주는 중간 역할
- 클라이언트는 Send 명령어를 통해서 메시지 전송
- Subscribe 명령을 통해서 메시지 구독
- Destination 헤더와 함께 메시지에 대한 전송이나 구독을 진행
- 브로커를 통해 연결된 다른 클라이언트로 메시지를 보내거나, 서버로 메시지를 보내 일부 작업을 요청함
Spring WebSocket에서 사용자별 메시지 라우팅 이해
Spring Websocket에서 특정 사용자에게 메시지를 전송하려면, 서버와 클라이언트가 서로 경로를 일치시켜야 합니다.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// topic: 1-1 | queue: 1-N
registry.enableSimpleBroker("/topic", "/queue");
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/queue");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.withSockJS();
}
- setUserDestinationPrefix 설정
- Spring에서 사용자가 특정한 목적지 경로를 구독할 때 “/queue”로 시작하는 경로를 사용하도록 지정
- convertAndSendToUser() 메서드와 함께 작동하여, 사용자의 세션 ID와 매핑된 경로로 메시지를 전달할 수 있게 함
- convertAndSendToUser
- messagingTemplate.convertAndSendToUser(user, "/queue/messages", message)를 호출하면,
실제로는 “/queue/{user}/queue/messages로 메시지가 전송됩니다. - {user}는 실제 사용자의 세션에 해당하는 ID
- messagingTemplate.convertAndSendToUser(user, "/queue/messages", message)를 호출하면,
클라이언트 측에서 구독 경로 설정
클라이언트에서 구독 경로를 “/queue/${nickname}/queue/messages로 설정하면, 이 경로는 setUserDestinationPrefix(”/queue”) 설정에 따라 Spring이 관리하는 사용자별 큐로 처리됩니다.
- 결국, 클라이언트가 특정 사용자(nickname)의 큐를 구독하게 되고, 서버는 이 경로로 메시지를 보낼 수 있습니다.
@MessageMapping & @SendTo
@MessageMapping("/user.addUser") //** 클라이언트에서 보내는 STOMP 메시지 처리 경로
@SendTo("/topic/user") //** '/topic/user'로 전송
public User adduser(@Payload User user) {
userService.saveUser(user);
return user;
}
- @MessageMapping 어노테이션은 클라이언트에서 보내는 STOMP 메시지를 처리하는 메서드를 정의합니다.
- @SendTo 어노테이션은 (스프링 프레임워크의 STOMP 메시징 시스템에서) 메시지를 브로커에게 전송할 때 사용됩니다.
- Controller의 메서드가 반환하는 메시지를 특정 목적지로 브로드캐스트할 때 유용합니다.
반응형