🕸️ Network

STOMP

정의

Simple Text Oriented Messaging Protocol 간단한 문자 기반 메세징 프로토콜
메시지 브로커를 활용하여 메시지 전송을 효율적으로 하기 위한 프로토콜
프로토콜: 메세지를 서로 주고 받을때 정의된 규칙 체계

목적 및 특징

  • 메시지를 공급하는 주체와 소비하는 주체를 분리해 제공하는 Publish-Subscribe 구조
  • 텍스트 기반, 바이너리 기반도 지원
  • 프레임(Frame)을 사용해 전송
  • TCP 또는 WebSocket과 같은 양방향 네트워크 프로토콜 기반으로 동작
    • WebSocket 위에 얹어 사용하는 하위 프로토콜
  • 메시지에 대한 스팩만을 정의하고 있기 때문에, 기능 구현은 전적으로 서버에 맡긴다.
  • 헤더 값을 기반으로 통신 시 인증처리를 구현 가능
  • 기존 포트(HTTP - 80, HTTPS - 443)를 사용

장점

  • Spring framework 및 Spring Security는 STOMP를 사용하여 WebSocket만 사용할 때보다 더 다채로운 모델링을 할 수 있다.
  • Messaging Protocol을 만들고 메세지 형식을 커스터마이징 할 필요없다.
  • 외부 Messaging Queue를 사용할 수 있다. (RabbitMQ, ActiveMQ, Apache Kafka)
  • WebSocket 기반으로 각 Connection(연결)마다 WebSocketHandler를 구현하는 것 보다 @Controller 된 객체를 이용해 조직적으로 관리할 수 있다.
    • 즉, 메세지는 STOMP의 "destination" 헤더를 기반으로 @Controller 객체의 @MethodMapping 메서드로 라우팅 된다.
  • STOMP의 "destination" 및 Message Type을 기반으로 메세지를 보호하기 위해 Spring Security를 사용할 수 있다.

Pub - Sub(발행 - 구독)

발신자(pub)가 메시지를 발행하면 수신자(sub)가 그것을 수신하는 메시징 패러다임

메시지 브로커

발신자의 메시지를 받아 수신자에게 메시지를 전달하는 주체

외부 메시지 브로커가 필요한 이유

notion image
서버가 여러개라면, 위와 같은 상황에서 사용자3은 메시지를 받지 못할 것이다.
notion image
  • 발행자가 서버1에 메시지를 보냈을때, 서버1에서는 메시지 브로커의 exchange에 메시지를 전달한다.
  • 외부메시지 브로커에 바인딩 되어 있는 사용자 1, 2, 3 큐에 메시지를 전달하게 되며, 다른 서버인 서버 2에 연결 중인 사용자 3에게도 메시지를 보낼 수 있게 된다.
  • 즉, 웹소켓 서버에 관계없이 구독중인 채널의 메시지를 받을 수 있게 된다.

외부 브로커 예시

  • RabbitMQ

Frame

명령(Command)과 추가적인 헤더(Header)와 추가적인 바디(Body)로 구성
  • HTTP와 유사
  • 첫번째 라인은 텍스트(Command 명령어)
  • 이후 key:value 형태로 header 정보를 포함
  • header이후에 공백 줄을 하나 더 추가하는 것으로 header의 끝을 설정
  • header이후에는 Payload(Body)가 존재
  • Payload(데이터)Body에 위치
  • NULL 문자로 설정
COMMAND key(header1):value1 key(header2):value2 ... BODY^@

COMMAND

  • CONNECT, SEND, SUBSCRIBE, UNSUBSCRIBE, BEGIN, COMMIT, ABORT, ACK, NACK, DISCONNECT

작동 원리

pub / sub란 메세지를 공급하는 주체와 소비하는 주체를 분리해 제공하는 메세징 방법이다. 기본적인 컨셉을 예로 들자면 우체통(topic)이 있다면 집배원(pub)이 신문을 우체통에 배달하는 행위가 있고, 우체통에 신문이 배달되는 것을 기다렸다가 빼서 보는 구독자(sub)의 행위가 있다. 이때 구독자는 다수가 될 수 있다. pub / sub 컨셉을 채팅방에 빗대면 다음과 같다.
채팅방 생성: pub / sub를 할 Topic이 생성됨
채팅방 입장: Topic을 sub
채팅방에서 메세지를 송수신: 해당 Topic으로 메세지를 송신(pub), 메세지를 수신(sub)

메시지의 흐름

notion image
STOMP Endpoint가 노출되고 나면, Spring 어플리케이션은 연결되어있는 Client들에 대해 STOMP 브로커가 된다
(/app == /pub, /topic == /sub) 아래 그림은 내장 메세지 브로커를 사용한 경우 컴포넌트 구성을 보여준다.

Spring-message

spring-message 모듈은 Spring framework의 통합된 Messaging 어플리케이션을 위한 지원을 한다.
  • Message : headers와 payload를 포함하는 메세지의 표현
  • MessageHandler : Message 처리에 대한 계약
  • SimpleAnnotationMethod : @MessageMapping 등 Client의 SEND를 받아서 처리한다.
  • SimpleBroker : Client의 정보를 메모리 상에 들고 있으며, Client로 메세지를 보낸다.
  • channel
    • clientInboundChannel : WebSocket Client로부터 들어오는 요청을 전달하며, WebSocketMessageBrokerConfigurer를 통해 intercept, taskExecutor를 설정할 수 있다.
      • 클라이언트로 받은 메세지를 전달
    • clientOutboundChannel : WebSocket Client로 Server의 메세지를 내보내며, WebSocketMessageBrokerConfigurer를 통해 intercept, taskExecutor를 설정할 수 있다.
      • 클라이언트에게 메세지를 전달
    • brokerChannel : Server 내부에서 사용하는 채널이며, 이를 통해 SimpleAnnotationMethod는 SimpleBroker의 존재를 직접 알지 못해도 메세지를 전달할 수 있다.
      • 서버의 어플리케이션 코드 내에서 브로커에게 메세지를 전달

구현

출처