221105 TIL [Spring boot + React]실시간 채팅 기능 구현하기 - 3 (with STOMP)

채팅 기능을 아직 구현하지는 못했지만 오늘 배우고 이해한 STOMP에 대해서 정리해보려고 한다.

 

STOMP를 사용하게 되면 text와 binary 두가지 유형의 메시지만 정의하는게 아니라 규격을 갖춘 메시지를 전달할 수 있다.

COMMAND
header1:value1
header2:value2

Body^@
  • COMMAND : SEND, SUBSCRIBE를 지시할 수 있다.
  • header : WebSocket만으로는 표현이 불가능한 header를 작성할 수 있다.
    • destination: 이 헤더로 메시지를 보내거나 구독을 할 수 있다. (pub/sub 구현)

 

예를 들어 아래 코드와 같이 유저A는 3번 채팅방을 구독할 수 있다.

SUBSCRIBE
destination: /subscribe/chat/room/3

 

유저B가 아래와 같이 채팅 메시지를 보낼 수 있다.

SEND
content-type: application/json
destination: /publish/chat

{"chatRoomId": 3, "type": "MESSAGE", "writer": "clientB"}

 

서버는 유저B가 보낸 내용을 메시지를 전송해줄 broker에게 전달한다.

MESSAGE
destination: /subscribe/chat/room/3

{"chatRoomId": 3, "type": "MESSAGE", "writer": "clientB"}

/subscribe/chat/room/3를 구독하고 있는 모든 사용자에게 메시지가 전송이 된다.

 

코드를 보면서 이해를 해보자

WebSocketConfig

WebSocketMessageBrokerConfigurer을 상속받아 registerStompEndpoints를 오버라이드 해준다.

  • addEndpoing : handshake와 통신을 담당해줄 endpoint를 설정해준다. (WebSocket 세션과 연결 == endpoint를 호출)
  • SockJS : WebSocket은 모든 브라우저가 지원하지 안힉 때문에 SockJS를 활용 할 수 있다.
  • enableSimpleBroker : 설정해준 경로로 SimpleBroker를 등록해준다.
    • SimpleBroker는 해당하는 경로를 SUBSCRIBE하는 client에게 메시지를 전달하는 역할을 한다.
    • 예를 들어 사용자 A,B,C가 각각 /pub/test1, /pub/test2, /pub/test1를 구독하고 있을때 /pub/test1로 메시지를 전송하면 사용자 A,C만 메시지를 받는 구조이다.
  • setApplicationDestinationPrefixes : client에서 SEND 요청을 처리한다.

Controller

  • SimpMessagingTemplate : config파일에서 붙여준 @EnableWebSocketMessageBroker 어노테이션을 통해서 등록되는 bean이다. 특정 broker에게로 메시지를 전달한다.
  • @MessageMapping :  클라이언트에서 보내는 메시지를 매핑한다. WebSocketConfig에서 등록한 applicationDestinationPrfixes와 @MessageMapping의 경로가 합쳐진다 (ex. /pub/chat/enter)
  • convertAndSend() : message에서 가져온 param에 해당하는 번호의 room을 구독하는 클라이언트에게 메시지를 전송