Simple Text Orientated Messaging Protocol의 약자이며, 중개 서버를 통해서 클라이언트간에 비동기적으로 메시지를 전송하기 위한 프로토콜이다. 클라이언트와 서버 간의 전달되는 텍스트 기반의 메시지 형식을 정의한다.
subscribe
/publish
기반으로 동작한다.
subscribe
: 하나의 채널(타깃)을 클라이언트가 구독한다.publish
: 하나의 채널(타깃)을 구독 중인 모든 클라이언트에게 메시지를 발행한다.STOMP는 HTTP를 모델로한 frame 기반의 프로토콜이다.
- frame은 command, optional header, optional body로 구성된다.
COMMAND
header1:value1
header2:value2
Body^@
텍스트 기반의 메시지 프로토콜이지만 binary 메시지의 전송도 허용한다.
STOMP 서버는 메시지가 전송될 수 있는 여러 destination으로 구성된다.
STOMP 클라이언트는 두 가지 모드의 동작을 할 수 있는 user-agent이다.
SEND
frame을 사용해 서버에게 메시지를 보낼 수 있다.SUBSCRIBE
frame을 사용해 특정 destination에 메시지를 보낼 수 있고 서버로부터 MESSAGE
frame을 받을 수 있다.@MessageMapping
을 사용해서 handler를 직접 구현하지 않고 controller를 따로 분리해서 관리할 수 있다.
- 빌드 도구:
gradle
- spring boot version:
2.3.8
implementation 'org.springframework.boot:spring-boot-starter-websocket'
WebScoketConfig
작성웹소켓 설정을 위해 먼저 config를 작성한다.
@EnableWebSocketMessageBroker
annotation을 사용해서 STOMP를 사용할 수 있게 설정한다.@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { }
registerStompEndpoints
method를 overide 한다.@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("*");
}
}
/ws
이다.setAllowedOrigins
를 미리 사용해서 허용할 origin을 등록해둔다.*
는 모든 origin 허용이다. (보안을 위해선 특정 origin만 등록하자...)configureMessageBroker
method를 overide 한다.@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("*");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/sub");
registry.setApplicationDestinationPrefixes("/pub");
}
}
enableSimpleBroker()
를 사용해서 /sub
가 prefix로 붙은 destination의 클라이언트에게 메시지를 보낼 수 있도록 Simple Broker를 등록한다.setApplicationestinationPrefiexs()
를 사용해서 /pub
가 prefix로 붙은 메시지들은 @MessageMapping
이 붙은 method로 바운드된다.통신시에 주고 받을 메시지 형식을 작성한다.
@Data
public class ChatDto {
private Integer channelId;
private Integer writerId;
private String chat;
}
@RestController
@RequiredArgsConstructor
public class WebSocketController {
private final SimpMessagingTemplate simpMessagingTemplate;
@MessageMapping("/chat")
public void sendMessage(ChatDto chatDto, SimpMessageHeaderAccessor accessor) {
simpMessagingTemplate.convertAndSend("/sub/chat/" + chatDto.getChannelId(), chatDto);
}
}
@MessageMapping
annotation은 메시지의 destination이 /hello
였다면 해당 sendMessage()
method가 불리도록 해준다.sendMessage()
에서는 simpMessagingTemplate.convertAndSend
를 통해 /sub/chat/{channelId}
채널을 구독 중인 클라이언트에게 메시지를 전송한다.SimpMessagingTemplate
는 특정 브로커로 메시지를 전달한다.chatDto
)로 들어온다.