백엔드

STOMP 란?

do_hyuk 2024. 1. 17. 14:09

오늘은 실시간 채팅 및 채팅방 동적 생성을 구현하기 위해 STOMP에 대해서 알아보겠다.

 

STOMP(Simple/Streaming Text Oriented Messaging Protocol) 텍스트 기반의 메시지 프로토콜이다.

클라이언트와 서버 간 전송할 메시지의 유형, 형식, 내용들을 정의한 규칙(FRAME)으로 TCP 또는 WebSocket과 같은

양방향 네트워크 프로토콜 기반으로 동작한다. HTTP와 같은 프로토콜에서 사용되는 request-response 패턴과 다르게,

브로커와 연결된 클라이언트 간에 메시지를 교환하는 방식으로 동작한다.

 

STOMP는 기본적으로 Publish-Subscribe 구조로 되어있으며, 이 구조는 메시지를 공급하는 주체와 소비하는 주체를 분리해

제공하는 메시징 프로토콜이다.


1. STOMP 사용하는 이유

  • 메시지의 형식(Frame)을 정의할 수 있어, 클라이언트와 서버 간의 통신에서 일관성을 유지할 수 있다.
  • pub/sub 구조로 되어있어 메시지를 전송하고 메시지를 받아 처리하는 부분이 확실히 정해져 있기 때문에 
    개발자 입장에서 명확하게 인지하고 개발할 수 있다.

  • 메시지 브로커를 사용할 수 있어, 메시지 전송 시 중계 역할을 하는 서버를 따로 두어
    메시지 전송의 안정성과 확장성을 높일 수 있다.

  • WebSocket 기반으로 각 Connection(연결)마다 WebSocketHandler를 구현하는 것보다 @Controller 된 객체를
    이용해 조직적으로 관리할 수 있다.
    (메시지는 STOMP의 "destination"헤더를 기반으로 @Controller 객체의 @MethodMapping 메서드로 라우팅 된다.)

  • STOMP의 "destination" 및 Message Type을 기반으로 메시지를 보호하기 위해 Spring Security를 사용할 수 있다.

2. STOMP Frame 구조

COMMAND
header1 : value1
header2 : value2

Body^@
  • COMMAND : 메세지의 타입을 나타내는 문자열이다. SEND, SUBSCRIBE, UNSUBSCRIBE 등이 있다.
  • header1, header2 : 추가 정보를 제공하는 헤더이다.
    • destination : 이 헤더로 메시지를 보내거나(SEND), 구독(SUBSCRIBE)할 수 있다.
  • Body : 메세지의 내용이다.
  • ^@ : NULL문자이다. Body의 끝을 나타낸다.

클라이언트는 메세지를 전송하기 위해 SEND, SUBSCRIBE COMMAND를 사용할 수 있다.

 

또한 SEND, SUBSCRIBE COMMAND 요청 Frame에는 메시지가 무엇이고, 누가 받아서 처리할지에 대한

Header 정보가 포함되어 있다.

 

이런 명령어들은 "destination" 헤더를 요구하는데 이것이 어디에 전송할지, 혹은 어디에서 메시지를 구독할 것 인지를 나타낸다.


3. STOMP destination 종류

[1]   /exchange (Multicast)

 SUBSCRIBE 프레임에서는 /exchange/<name>[/<pattern>] 형식의 목적지를 사용할 수 있다.

→  <pattern>이 제공된 경우, 큐를 <name> Exchange에 <pattern>으로 바인딩하고 큐 구독을 등록한다.

 

SEND 프레임에서는 /exchange/<name>[/<routing-key>]의 형식을 사용한다.

   <routing-key>를 사용하여 Exchange <name>로 전송한다.

 

각 구독자마다 새 큐가 생성되어 지정된 Exchange에 라우팅 키를 사용하여 바인딩된다. 기존 큐를 사용하려면

/amq/queue 목적지를 사용해야 한다.


[2]   /topic (Broadcast)

/topic은 STOMP 클라이언트에서 가장 일반적으로 사용되는 목적지 유형이며, /topic/<name> 형식이다.

이것은 구독자 패턴에 대한 토픽 매칭을 수행하며, 메시지를 여러 구독자에게 라우팅할 수 있다.


[3]   /queue (Unicast)

/queue는 간단한 대기열을 처리하기 위해 사용된다. /queue/<name> 형식을 사용하면 좋다. 큐 목적지는 각 메시지를

최대 한명의 구독자에게 전달하며, 구독자가 없으면 구독자가 없으면 구독자가 큐에 연결할 때까지 큐에 대기한다.

   SUBSCRIBE 프레임에서는 <name>의 공유 큐를 생성하고 현재 STOMP 세션에 대해 <name>의 공유 큐를 구독한다.