Spring/Issue

Stomp를 활용한 웹소켓 구현

블로그 주인장 2024. 1. 24.

서론

Stomp를 이용하여 웹소켓을 구현하는 방법에 대해 알아보겠습니다.

 

이전 포스팅에서 Stomp에 관한 개념에 대해 설명했었습니다.

https://miiro-under.tistory.com/272

 

Message Broker STOMP 개념

서론 Message를 송-수신할 때 사용하는 MessageBroker 중 STOMP 프로토콜에 대해 알아보겠습니다. STOMP란? Simple Text Oriented Messaging Protocol 의 약자로써, WebSocket의 서브 프로토콜 입니다. 웹소켓은 Text와 Bina

miiro-under.tistory.com

 

Stomp를 이용해서 간단하게 채팅 서비스를 구현해보겠습니다.

 

코드 구현

 

의존성(build.gradle)

dependencies {
    //web-socket
    implementation 'org.springframework.boot:spring-boot-starter-websocket'
}

 

웹소켓을 사용하기 위해서 의존성(dependencies)를 추가하겠습니다.

 

Spring Stomp 환경 설정

Spring 프로젝트에서 WebSocket 및 STOMP 메시지를 활성화 하기 위한 Spring Configuration을 설정하겠습니다.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

  @Override
  public void configureMessageBroker(MessageBrokerRegistry registry) {
    //클라이언트에게 메시지 전달
    registry.enableSimpleBroker("/topic");
    //클라이언트의 Send 요청 처리
    registry.setApplicationDestinationPrefixes("/app");
  }

  @Override
  public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/ws")
        .addInterceptors()
        .setAllowedOriginPatterns("*");
  }
}

 

@EnableWebSocketMessageBroker 는 메시지 브로커가 지원하는 WebSocket 메시지 처리를 활성화시킵니다.

 

configureMessageBroker( ) 메서드는 WebSocketMessageBrokerConfigurer 인터페이스의 기본 메소드를 구현하여 메시지 브로커로 구성합니다.

 

1. registry.enableSimpleBroker("/topic")

  • 메시지를 받을 때의 관련 경로를 설정합니다.
  • "/queue", "/topic" 이 두 경로가 prefix(api 경로의 맨 앞)에 붙은 경우,
    messageBroker가 잡아서 Subscriber에게 메시지를 보낸다.
  • 주로 "/queue" 는 1:1 인 경우, "/topic"은 1:N의 경우에 주로 사용한다.

 

2. registry.setApplicationDestinationPrefixes("/app")

  • 메시지를 보낼 때 관련 경로를 설정한다.
  • @MessageMapping 주석이 달린 메서드에 바인딩된 메시지의 "/app" 접두사를 지정한다.
  • 위처럼 prefix를 "/app"/으로 설정했다면 "/topic/hello" 라는 토픽에 구독을 신청할 때 실제 경로는 "/app/topic/hello" 가 됩니다.

3. registerStompEndpoints( )

  • Client에서 webSocket을 연결할 때 사용할 API 경로를 설정해주는 메서드이다.
  • 위의 예시처럼 진행한다면 웹소켓을 연결할 때 사용하는 주소인 ws://localhost:8080 에  /ws 를 추가하면 된다.

 

Controller 구현

public class ChatMessageController {

  private final SimpMessageSendingOperations sendingOperations;

  @MessageMapping("/chat/message/{roomId}")
  public void sendMessage(@Payload ChatMessageRequest chat,
                          @DestinationVariable("roomId") Long roomId) {
    sendingOperations.convertAndSend("/topic/chatRoom/" + roomId, chat.getMessage());
    log.info("Message [{}] send by member: {} to chatting room: {}",
        chat.getMessage(), chat.getMemberId(), roomId);
  }
}

 

SimpleMessagingTemplate은 @EnableWebSocketMessageBroker를 통해 등록되는 Bean으로, Broker에게 메시지를 전달한다.

 

클라이언트가 메시지를 보내는 경로인 @MessageMapping 경로는 WebSocketConfig에서 등록한 prefix와 합쳐진다.

위의 예시를 들면 "/app/chat/message/{roomId}" 형태가 된다.

 

위의 @DestinationVariable은 구독 및 발행 URL 경로변수를 지정한다.

 

Request Dto 구현

@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ChatMessageRequest {

  private Long memberId;

  private String message;
  private MessageType messageType;
}

 

apic를 활용한 Stomp 통신 테스트하기

Stomp 테스트 툴인 APIC을 이용해서 테스트를 진행해보겠습니다.

APIC 툴은 해당 apic — The complete API solution 에서 다운받으시면 됩니다.

본인의 OS(Windows, Mac)에 맞게 release 버전을 사용하면 됩니다.

 

apic 공식사이트 접속이 되지 않지 않은 분들은(저의 경우도 포함)

해당 링크 에서 다운받아서 사용 가능합니다.

 

 

1. apic 실행 후에 Test 에서 New Tab 우측 ws 버튼을 누른다.

 

2. 커넥션 정보를 입력합니다.

 - 본인이 스프링프로젝트에서 설정한 WebSocketEndPoint를 입력하면 됩니다.

 - 입력 후에 Connect 버튼을 눌러 연결이 완료되면 "Stomp Connected" 메시지가 출력된다.

 

 

3. 테스트 데이터 전송

- 전송 버튼을 누르면 "/app/chat/message/1" 로 해당 정보를 전송한다.

- 전송된 정보는 구독을 동일하게 진행한 다른 사용자에게 노출된다.

 

4. 테스트 데이터 확인

- 구독하고 있는 URL인 "/topic/chatRoom/1" 에서 확인하면된다.

- 위의 이미지에서 보낸 정보인 "Chatting" 이 메시징 되는 것을 확인할 수 있다.

 

 

 

본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다.

반응형

'Spring > Issue' 카테고리의 다른 글

[JPA] fetch-Join을 이용한 N+1 문제 해결  (1) 2024.01.26
SMTP 비동기로 보내기(@Async)  (2) 2024.01.09
JPA Persistable 로 엔티티 구별하기  (0) 2024.01.08

댓글