Springboot

[Spring] Websocket + Stomp을 통한 실시간 통신

KJihun 2024. 2. 27. 21:37
728x90

 

 

 

1. 의존성 주입

	implementation 'org.springframework.boot:spring-boot-starter-websocket'
	implementation 'org.webjars:stomp-websocket:2.3.4'
	implementation 'org.webjars:sockjs-client:1.5.1'

 

 

2. webSocketConfig

@Configuration
@RequiredArgsConstructor
@EnableWebSocketMessageBroker
@Slf4j
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    private final StompHandler stompHandler;


    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/pub");     //클라이언트에서 보낸 메세지를 받을 prefix
        registry.enableSimpleBroker("/sub");    //해당 주소를 구독하고 있는 클라이언트들에게 메세지 전달
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        log.info("WebSocket 연결");
        registry.addEndpoint("/api/v1/room")   //SockJS 연결 주소
            .setAllowedOriginPatterns("**")           //모든 요청 수락
//            .withSockJS() //버전 낮은 브라우저에서도 적용 가능()
                            //구독자가 존재하지 않을 경우(Invalid SockJS path - required to have 3 path segments)
        ;
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(stompHandler);
    }
}

 

 

 

3. stompHandler

@Slf4j
@Component
@RequiredArgsConstructor
public class StompHandler implements ChannelInterceptor {

  // Socket 통신 상태
  @Override
  public Message<?> preSend(Message<?> message, MessageChannel channel) {
    StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
    if(StompCommand.CONNECT.equals(accessor.getCommand())){
      log.info("CONNECT");
    }else if(StompCommand.SUBSCRIBE.equals(accessor.getCommand())){
      log.info("SUBSCRIBE");
    }else if(StompCommand.DISCONNECT.equals(accessor.getCommand())){
      log.info("DISCONNECT");
    }
    log.info("message: {}", message);
    return message;
  }
}

 

 

 

 

접속

http로 접속 시, 검은 화면에 Can "Upgrade" only to "WebSocket". 만 적혀있다면 정상적으로 동작하는 것이다. websocket 전용이기에 http나 https로 접속할 수 없다.

 

WebSocket 프로토콜인 "ws://"와 "wss://" 로 접속하면 어떻게 될까?

ERR_UNKNOWN_URL_SCHEME가 뜬다.

처음에는 에러인줄 알고 당황했으나 

보통 웹 브라우저는 WebSocket 프로토콜을 네이티브 기능으로는 지원되지 않기 때문이었다.

 

테스트

 

WebSocket Debug Tool

 

jxy.me

 

subscribe 

 

 

 

STOMP subscribe destination에는 구독할 주소,

STOMP send destination에는 메세지를 보낼 주소를 입력한 후 메세지를 보내면 된다.

이후에는 kafka나 rabbitmq같은 메세지 브로커를 추가하여 사용해볼 계획이다.

'Springboot' 카테고리의 다른 글

[Security] Spring Security의 흐름  (0) 2024.06.22
[Springboot] JWT 0.15.2  (0) 2024.06.22
[Springboot] QueryDSL 2  (0) 2023.08.09
[Springboot] QueryDSL  (0) 2023.08.08
[SpringBoot] Redis Caching  (0) 2023.08.06