[Road To MQ] WebSocket + STOMP로 실시간 통신

CodeKong의 기술 블로그·2024년 1월 23일
3

Road To MQ

목록 보기
2/6
post-thumbnail

안녕하세요 오늘은 Road To MQ 두 번째 아티클인 WebSocket + STOMP입니다!

대부분 WebSocket에 stomp를 올려서 사용하는 만큼 잘 정리해서 테스트 해보겠습니다!

📌 배경

STOMP(Simple Text Oriented Messaging Protocol)

말 그 대로 프로토콜입니다. 자체로 통신 규약을 가지고 있습니다.
command, header, body로 이루어진 frame으로 구성되어 있습니다.

⭐ 특징으로 pub / sub 구조를 가지고 있습니다.

pub / sub

pub / sub는 뉴스구독이라고 생각하면 편합니다!
pub는 뉴스발행 broker는 판매원 sub는 뉴스 수신입니다.

pub / sub의 장점

✅ 느슨한 결합 : publisher는 subscriber가 누군지 모릅니다. 반대도 마찬가지죠
✅ 확장성 : 데이터가 1:1로 전송되는 것이 아니기 때문에 수많은 publisher와 subscriber가 등록가능합니다.


📌 기본 설정

🛠️ 의존성 추가

//WebSocket
implementation 'org.springframework.boot:spring-boot-starter-websocket'

implementation 'org.webjars:sockjs-client'
implementation 'org.webjars:stomp-websocket'

먼저 WebSocket과 STOMP을 위한 의존성을 추가해줍니다.


이제부터는 WebSocket에 관한 Config 설정을 하겠습니다❗

Config 설정

@Configuration
@EnableWebSocketMessageBroker //WebSocket 서버를 활성화
public class StompConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws/chat").setAllowedOrigins("*").withSockJS(); //엔드포인트 등록
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //메시지 브로커가 해당 api를 구독하고 있는 클라이언트에게 메시지를 전달
        registry.enableSimpleBroker("/sub");
        registry.setApplicationDestinationPrefixes("/pub"); //메시지를 발행하기 위한 prefix
    }
}

WebSocketMessageBrokerConfigurer를 구현하여 Config 합니다.

registerStompEndpoints

addEndpoint : stomp을 사용하기 위한 소켓 연결 EndPoint입니다.

configureMessageBroker

✅ configureMessageBroker : 구독을 위한 연결주소입니다. "/sub"를 등록했으므로
"/sub/**" 의 엔드포인트로 오는 데이터는 해당 토픽을 구독한 클라이언트에 전송됩니다.

✅ setApplicationDestinationPrefixes: 메세지를 발행하기 위한 연결주소입니다. "/pub"를 등록했으므로
"/pub/**" 의 엔드포인트로 오는 데이터는 해당 controller로 연결됩니다.

Controller

@Controller
@RequiredArgsConstructor
public class StompController {

    @MessageMapping("/hello")
    @SendTo("/sub/greetings")
    public String greeting(String message) throws Exception {
        return message;
    }

}

간단한 controller입니다.

@MessageMapping("/hello")

이전 config에서 발행을 위한 prefix를 /pub로 설정했으므로
ws://localhost:8080/pub/hello의 엔드포인트로 들어오는 요청은 해당 controller에 연결됩니다.

@SendTo("/sub/greetings")

반환값을 해당 엔드포인트로 전달합니다.
"/sub/greetings"를 구독한 모든 구독자에게 데이터를 전송합니다.


📌 테스트

현재 프로젝트의 프론트 부분을 streamlit으로 구현하고있어서 python으로 구현하려고 했지만 쓰레드 문제 때문에 간단한 테스트로 진행하여야 했습니다.

하지만 기존에 많이 쓰였던 Apic 확장 프로그램도 현재 접속이 되지않아 구글링하던 중
https://jxy.me/websocket-debug-tool/ 사이트를 알게되어 테스트 하였습니다.

WebSocket 연결


url입력 & STOMP를 체크 후 연결

잘 연결되었고 다른 창에도 같은 방식으로 연결해줍니다.

구독


창1에서 구독 엔드포인트를 입력해주고 구독해줍니다.

발행

창2에서 발행 엔드포인트와 메세지를 입력해주고 send를 눌러줍니다!

창2에서의 발행

창1에서의 수신

로그가 잘 찍히는 것을 볼 수 있습니다!🔫🔫

0개의 댓글