0. 도입 : HTTP 에서의 양방향 통신의 한계

먼저 우리는 양방향 통신에 대해서 고민해보아야 합니다. http는 전형적인 단방향 통신을 거치는 프로토콜입니다. 통신이 필요하다면, 클라이언트가 요청하고 서버가 응답해야 합니다.

 

만약 http 에서 양방향 통신이 필요하다면, 다음과 같은 방식들을 사용해야합니다.

 

Polling : 클라이언트가 주기적으로 서버에 요청을 보내 응답을 기다리는 방식

Long Polling : 요청을 보내고, 서버에서 데이터가 생길 때까지 기다린 후 응답을 보내는 방식

Streaming : 응답 연결을 확인받지 않고 계속해서 데이터를 전송만 하는 방식. (UDP와 유사한 비신뢰적 느낌)

 

하지만 이러한 방식들은 한계가 있습니다.

누구와 어떤 메시지를 어떻게 실시간으로 통신할 것인가? 에 대한 체계가 잘 잡혀있지않죠.

 

그래서 나온 것이 웹소켓입니다.

 

1. WebSocket(웹 소켓)의 등장

WebSocket은 HTTP 위에서 동작하면서 양방향 통신을 가능하게 하는 프로토콜입니다. 처음 한 번의 핸드셰이크(handshake)를 통해 연결을 맺고 나면, 서버와 클라이언트는 끊김 없는 상태에서 자유롭게 메시지를 주고받을 수 있습니다. 즉, 웹 소켓을 사용하면 보내는 이와 메시지를 담아서 실시간으로 통신이 가능하죠. 이로 인해 실시간성이 필요한 서비스(채팅, 게임 등)에서 WebSocket은 필수 기술입니다.

 

그러나 WebSocke 자체도 완전한 해결책이 될 수는 없습니다.

 

메시지 전송 방식, 수신자 식별, 채널 분리, 메시지 라우팅 등에 대한 구체적인 규칙(컨벤션)이 부족합니다.

 

구체적인 규칙이 부족하면 발생하는 문제는 무엇일까요?

누가 누구에게 보낸건지 알 수 없습니다.

어떤 메시지 형식으로 데이터가 전송된 것인지 파악하고 파싱하기 어렵습니다.

 

비유하자면, 랜덤 채팅이라고 생각해봅시다. 어떤 언어를, 누가, 어떤 방식으로 보내올지 알수 없습니다. 그러나 우리는 교내/사내 혹은 친구들끼리만, 같은 언어로, 예상 가능한 형식의 메시지를 전송받고 싶은 겁니다. 누군가의 메시지에는 날짜가 포함되어 있고, 누군가의 메시지에는 채팅 제목이 없고, 식의 알수없는 프로토콜은 안됩니다.

 

2. 그래서 등장한 STOMP

STOMP(Simple Text Oriented Messaging Protocol)는 WebSocket 위에서 동작하는 경량 메시지 전송 프로토콜로, 구조화된 메시지 송수신 체계를 제공합니다. STOMP를 사용하면 다음과 같은 이점을 얻을 수 있습니다.

 

1. Topic(채널) 기반의 Pub/Sub

메시지는 destination 경로에 따라 전달되고, 해당 토픽(채널)을 구독(Sub: subscribe)한 클라이언트만 메시지를 수신할 수 있습니다! 즉 `누구와` 혹은 `누구의` 메시지를 주고받을지 지정할 수 있습니다.

 

2. 명령이 구조화되어 있다!

SEND, SUBSCRIBE, UNSUBSCRIBE, CONNECT, DISCONNECT 등의 명령이 존재해, 메시지 송수신 흐름이 명확하게 컨트롤됩니다.

 

3. url 경로를 통한 라우팅

예시를 들자면, /app/chat.sendMessage, /chat/public 등으로, 특정 채팅방, 시스템 메시지, 알림 등을 분류하기 쉽습니다. 즉, 목적별로 메시지를 분류할 수 있게 된겁니다!

 

4. 외부 라이브러리 연동 가능

보안(Spring Security) 적용이나 외부 메시지 브로커(Redis, RabbitMQ) 연동에도 적합합니다~

 

 

정리

WebSocket은 실시간 통신을 가능하게 하지만, 누가 어떤 메시지를 어떻게 주고받는지에 대한 구조가 부족합니다. 그래서 STOMP를 도입하면 topic 기반으로 메시지를 구분하고, 브로커를 통해 메시지를 전달해줄 수 있어 확장성과 메시지 라우팅이 수월해집니다.

 

특히 Spring에서 STOMP 구조를 사용하면 REST API처럼 각 메시지의 흐름을 URL 기반으로 정의하고, 컨트롤러 메서드로 처리할 수 있어 구조적입니다. 메시지 브로커를 통해 구독자에게 실시간 메시지를 푸시하는 방식은 REST의 GET 요청을 이벤트 기반으로 대체한 개념이라 볼 수 있고, REST의 경량 실시간 버전이라 할 수 있을 정도로, 구조, 처리 방식, 라우팅이 매우 유사하고 친숙합니다.

 

 

참고 자료

+ Recent posts