반응형
개요
클릭 미! 프로젝트를 진행하면서 웹 소켓을 통한 양방향 통신이 필요했고 이를 사용하기 위해 학습했다!
본론
해당 포스트에서는 스프링에서 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 접두사를 설정한다.
- enableSimpleBroker() : 스프링에서 제공해주는
따라서 publisher는 /app
접두사로 시작하는 경로로 데이터를 퍼블리싱하고, subscriber는 /topic
접두사가 붙은 큐를 구독함으로써, 데이터를 수신할 수 있다.
- registerStompEndpoints : STOMP로 메시지를 송수신하기 위한, 웹 소켓을 연결 설정을 하기 위한 메서드이다.
- addEndpoint() : 웹 소켓을 연결하기 위한 엔드포인트 설정
hostname/connect
로 설정해주었다. - setAllowedOriginPatterns() : CORS를 허용하는 호스트 패턴 (Web에서 사용되는 것과 별개로 설정해줘야 한다.)
- withSockJS() : 웹 소켓 통신이 불가능한 브라우저에서도 사용할 수 있도록 http로 소켓을 연결할 수 있도록 해준다. (front에서도 SockJS를 사용해야한다.)
- addEndpoint() : 웹 소켓을 연결하기 위한 엔드포인트 설정
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' 카테고리의 다른 글
[Spring Boot] 등록 요청의 중복 방지하기, 멱등성 보장 (0) | 2024.08.01 |
---|---|
[Spring Boot] 스프링 동시성 제어하기 (Java Synchronized keyword) (1) | 2024.04.25 |
[Spring Boot] Spring Boot에서 JPA QueryDSL 적용 방법 (0) | 2024.04.17 |
[Spring Boot] 도커 컨테이너에 환경에서 application.yml 민감한 정보 환경변수로 묶어내기 (0) | 2024.04.04 |
[Spring] 스프링 프로젝트에 카카오 로그인, 회원가입 구현 - (2) (0) | 2024.03.31 |