[Spring WebSocket] Spring WebSocket에서 STOMP를 사용해보자~~

2024. 12. 9. 13:12·Spring
반응형

 

개요

클릭 미! 프로젝트를 진행하면서 웹 소켓을 통한 양방향 통신이 필요했고 이를 사용하기 위해 학습했다!

본론

해당 포스트에서는 스프링에서 WebSocket, STOMP(Stream Text Oriented Messaging Protocol)의 사용 방법을 기재한다.

build.gradle

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
  • Spring Web과 WebSocket을 추가해준다!

먼저 나는 웹 소켓에 STOMP를 사용하여 규격이 있는 메시지를 송수신하도록 했다.

WebSocket

  • 웹 소켓 등록은 다음과 같이 해준다.
@EnableWebSocketMessageBroker
@Configuration
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    // 메시지 브로커 설정
    @Override
    public void configureMessageBroker(final MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }

    // WebSocket 연결 엔드포인트 설정
    @Override
    public void registerStompEndpoints(final StompEndpointRegistry registry) {
        registry.addEndpoint("/connect").setAllowedOriginPatterns("*").withSockJS();
    }
}
  • configureMessageBroker : 메시지 브로커를 설정한다. (STOMP는 publisher - subscriber가 존재하여, messaging queue가 존재한다. )
    • enableSimpleBroker() : 스프링에서 제공해주는 SimpleBroker 를 등록해주는데, /topic 접두사로 시작하는 경로로 설정해주었다.
    • setApplicationDestinationPrefixed() : 클라이언트에서 송신할때의 destination 접두사를 설정한다.

따라서 publisher는 /app 접두사로 시작하는 경로로 데이터를 퍼블리싱하고, subscriber는 /topic 접두사가 붙은 큐를 구독함으로써, 데이터를 수신할 수 있다.

  • registerStompEndpoints : STOMP로 메시지를 송수신하기 위한, 웹 소켓을 연결 설정을 하기 위한 메서드이다.
    • addEndpoint() : 웹 소켓을 연결하기 위한 엔드포인트 설정 hostname/connect 로 설정해주었다.
    • setAllowedOriginPatterns() : CORS를 허용하는 호스트 패턴 (Web에서 사용되는 것과 별개로 설정해줘야 한다.)
    • withSockJS() : 웹 소켓 통신이 불가능한 브라우저에서도 사용할 수 있도록 http로 소켓을 연결할 수 있도록 해준다. (front에서도 SockJS를 사용해야한다.)

publisher의 메시지 전송

  • 클라이언트에서 메시지를 전송해줄때 사용할 엔드포인트는 다음과 같이 만들어준다.
@MessageMapping("/start/{roomId}/{username}")
public void gameReady(
        @DestinationVariable("roomId") final String roomId,
        @DestinationVariable("nickname") final String nickname
) {
    gameService.readyGame(roomId, nickname);
}
  • @MessageMapping 어노테이션을 통해 엔드포인트를 설정할 수 있다.
    • 실제 엔드포인트는 /app/start/{roomId}/{username} 이된다.
  • 스프링에서 메시지를 전송하기 위해서는 다음과 같이 만들어줄 수 있다.
@Service
public class RoomBroadcastServiceImpl implements RoomBroadcastService {
    private static final MessageHeaders MESSAGE_HEADERS = new MessageHeaders(
            Collections.singletonMap("content-type", MimeTypeUtils.APPLICATION_JSON));
    private final SimpMessagingTemplate messagingTemplate;

    public RoomBroadcastServiceImpl(
            @Autowired final SimpMessagingTemplate messagingTemplate
    ) {
        this.messagingTemplate = messagingTemplate;
    }

    @Override
    public void broadcast(final String roomId, final Object data, final ResponseType type) {
        messagingTemplate.convertAndSend(
                토픽_url,
                전달할_data,
                MESSAGE_HEADERS
        );
    }
}
  • SimpleMessagingTemplate 를 이용해 메시징 큐에 데이터를 전달할 수 있다.
    • topic_url에 해당하는 큐에, 전달할_data가 전달된다.

ExceptionHandler

추가로, MessageMapping을 통한 처리에서 예외가 발생할때, ExceptionHandler를 설정해줄 수 있다.

@RestControllerAdvice
public class ControllerAdvisor {

    private final RoomBroadcastService roomBroadcastService;

    public ControllerAdvisor(
            @Autowired RoomBroadcastService roomBroadcastService
    ) {
        this.roomBroadcastService = roomBroadcastService;
    }

    @MessageExceptionHandler
    public void handleException(final CustomException exception) {
        roomBroadcastService.broadcast(
                exception.getRoomId(),
                exception.getErrorDTO(),
                ResponseType.ERROR
        );
    }
}
  • @MessageExcceptionHandler 를 사용하면, 쉽게 예외를 잡아서 사용할 수 있다.
반응형

'Spring' 카테고리의 다른 글

[JPA] JPA의 entity 상태와 영속성 컨텍스트의 기능들  (1) 2025.05.26
[ Spring Boot ] CommandLineRunner와 ApplicationRunner  (2) 2025.04.20
[Spring Boot] 등록 요청의 중복 방지하기, 멱등성 보장  (0) 2024.08.01
[Spring Boot] 스프링 동시성 제어하기 (Java Synchronized keyword)  (2) 2024.04.25
[Spring Boot] Spring Boot에서 JPA QueryDSL 적용 방법  (3) 2024.04.17
'Spring' 카테고리의 다른 글
  • [JPA] JPA의 entity 상태와 영속성 컨텍스트의 기능들
  • [ Spring Boot ] CommandLineRunner와 ApplicationRunner
  • [Spring Boot] 등록 요청의 중복 방지하기, 멱등성 보장
  • [Spring Boot] 스프링 동시성 제어하기 (Java Synchronized keyword)
부기(창의)
부기(창의)
창의의 개발블로그입니다.
  • 부기(창의)
    창의
    부기(창의)
  • 전체
    오늘
    어제
    • 분류 전체보기 (221) N
      • 고민 (1)
      • 데브옵스 (9)
      • AWS (3)
      • 웹 (13)
      • Docker (2)
      • Git (1)
      • JAVA (14) N
      • OOP (3)
        • 디자인 패턴 (1)
      • 백준 (106)
        • JAVA (7)
      • Spring (23)
      • 개발 관련 (4)
      • 알고리즘 (4)
      • TIL (13)
      • 우아한 테크코스 (9)
        • 프리코스 지원과정 (6)
      • NextJS (3)
      • Computer Science (13)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • Github : https://github.com/chan⋯
  • 인기 글

  • 태그

    페스타타북
    동시성
    자바
    다이나믹 프로그래밍
    우테코
    스프링
    spring
    java
    ec2
    우테코 7기
    jpa
    Spring Boot
    백준
    뉴진스
    페스타북
    도커
    메모리
    dp
    운영체제
    스레드
    hibernate
    완탐
    jvm
    OS
    SSR
    우테코 프리코스
    완전탐색
    aws
    알고리즘
    백트래킹
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
부기(창의)
[Spring WebSocket] Spring WebSocket에서 STOMP를 사용해보자~~
상단으로

티스토리툴바