[Spring Boot] WebSocket & STOMP 사용 방법

WebSocket 이란

웹소켓(WebSocket)은 하나의 TCP 접속에 전이중 통신 채널을 제공하는 컴퓨터 통신 프로토콜이다. 웹소켓 프로토콜은 2011년 IETF에 의해 RFC 6455로 표준화되었으며 웹 IDL의 웹소켓 API는 W3C에 의해 표준화되고 있다. 위키백과

HTTP 프로토콜과 호환되며, 실시간 양방향 통신을 제공하기 위한 프로토콜이며 Spring 4.0에서 등장한 네트워크 서비스입니다. (접속까지는 HTTP 프로토콜을 사용하지만 이후 WebSocket 프로토콜로 변경)

Spring Boot로 구현하기

Spring Boot에서 WebSocket과 자바스크립트에서 STOMP을 사용하여 메시지를 주고받는 예제를 구현해 보려고 합니다.

의존성 추가

pom.xml에 spring-boot-starter-websocket를 추가합니다.

1
2
3
4
5
<!-- 웹소켓 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

WebSocketConfig 설정

웹 소켓을 사용하기 위한 설정 파일이 필요합니다.

  • @Configuration을 통해 해당 파일이 Bean 설정을 할 것을 나타냅니다.
  • @EnableWebSocketMessageBroker 을 통해 WebSocket 사용을 나타냅니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

/**
* 클라이언트가 웹 소켓 서버에 연결하는데 사용할 웹 소켓 엔드포인트 등록
* withSockJS 를 통해 웹 소켓을 지원하지 않는 브라우저에 대해 웹 소켓을 대체한다.
* +)메소드명에 STOMP가 들어가는 경우 통신 프로토콜인 STOMP구현에서 작동된다.
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").setAllowedOriginPatterns("*").withSockJS();
}

/**
* 한 클라이언트에서 다른 클라이언트로 메시지를 라우팅하는데 사용될 메시지 브로커
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// topic으로 시작되는 요청을 구독한 모든 사용자들에게 메시지를 전달한다.
registry.enableSimpleBroker("/topic");

// 클라이언트에서 보낸 메세지를 받을 prefix
registry.setApplicationDestinationPrefixes("/app");
}
}

MessageDTO 생성

메시지 내용을 담아줄 MessageDTO를 생성합니다.

1
2
3
4
5
6
7
@Data
public class MessageDTO {

private String content;

private String sender;
}

MessageController 생성

/app/sendMessage 경로를 통해 전송되면 @MessageMapping과 매핑되어 메서드를 호출합니다. 그리고 @SendTo를 통해 /topic/message를 구독하고 있는 사용자에게 MessageDTO를 JSON 형식으로 전달합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Controller
public class MessageController {

/**
* /message/sendMessage로 요청이 들어오면 해당 메소드로 처리된다.
* @param message
* @return
*/
@MessageMapping("/sendMessage")
@SendTo("/topic/message")
public MessageDTO message(MessageDTO message) {
System.out.println("메세지 도착 :" + message);
return message;
}
}

@SendTo Annotation이 아닌 SimpMessagingTemplate을 사용해서 메세지를 전달할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Controller
@RequiredArgsConstructor
public class MessageController {

private final SimpMessagingTemplate simpMessagingTemplate;

/**
* /message/sendMessage로 요청이 들어오면 해당 메소드로 처리된다.
* @param message
*/
@MessageMapping("/sendMessage")
@SendTo("/topic/message")
public void message(MessageDTO message) {
System.out.println("메세지 도착 :" + message);
simpMessagingTemplate.convertAndSend("/topic/message", message);
}
}

STOMP 사용

STOMP는 Simple Text Oriented Messaging Protocol의 약자입니다. 클라이언트와 서버가 서로 통신하는 데 있어 메시지의 형식, 유형, 내용 등을 정의해 주는 프로토콜이라고 할 수 있습니다. STOMP를 사용하게 되면 단순한 Binary, Text가 아닌 규격을 갖춘 메시지를 보낼 수 있습니다.

라이브러리 추가

sockjs와 stomp 라이브러리를 추가합니다.

1
2
3
4
<!-- sock js -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.2/sockjs.min.js"></script>
<!-- STOMP -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>

메시지 받기

클라이언트에서는 다음과 같이 연결하고 구독을 합니다.

1
2
3
4
5
6
7
8
9
10
function subscribeMessage() {
let socket = new SockJS('/websocket');
let stompClient = Stomp.over(socket);

stompClient.connect({}, function () {
stompClient.subscribe('/topic/message', function (message) {
console.log(message.body);
});
});
}

메시지 전송

메세지 전송 시 실행되는 함수입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
function sendMessage() {
const socket = new SockJS('/websocket');
const stompClient = Stomp.over(socket);

stompClient.connect({}, function () {
const message = {
content: 'test',
sender: 'hgko',
};
stompClient.send('/app/sendMessage', {}, JSON.stringify(message));
stompClient.disconnect();
});
}

결론

Spring Boot 환경에서 WebSocket과 STOMP를 활용한 메시지 전송 기능 구현에 대해 알아보았습니다.

쉽게 구현할 수 있어 적용이 빠를 것 같습니다.

Share