Spring Boot WebSocket

플레이어가 참여할 수 있는 퀴즈 방, 채팅과 이모지 기능 등을 구현하기 위해 웹소켓을 공부했다.

메세징 기능을 위해 메모리 기반의 STOMP 메세지 브로커를 사용했다. 이외에도 Kafka, RabbitMQ 등 메세징 시스템을 사용할 수도 있다.

WebSocket

웹소켓은 단방향이 아닌 양방향 통신을 가능하게 해주는 프로토콜 기술로, 클라이언트와 서버 간 실시간 통신이 필요할 때 사용한다.

웹소켓은 Handshake 과정을 거쳐 연결을 수립한다. 연결이 수립되고 나면 소켓 연결이 닫힐 때까지 실시간으로 데이터를 주고 받을 수 있다.

STOMP

STOMP는 Simple Text Oriented Messaging Protocol의 약자이다. WebSocket 프로토콜은 Text 또는 Binary 두 가지 유형의 메시지 타입은 정의하지만 메시지의 내용에 대해서는 정의하지 않는다. 즉, WebSocket만 사용해서 구현하게 되면 해당 메시지가 어떤 요청인지, 어떤 포맷으로 오는지, 메시지 통신 과정을 어떻게 처리해야 하는지 정해져 있지 않아 일일이 구현해야 한다. 따라서 STOMP라는 프로토콜을 서브 프로토콜로 사용한다. STOMP는 클라이언트와 서버가 서로 통신하는 데 있어 메시지의 형식, 유형, 내용 등을 정의해주는 프로토콜이라고 할 수 있다. STOMP를 사용하게 되면 단순한 Binary, Text가 아닌 규격을 갖춘 메시지를 보낼 수 있다. 스프링은 spring-websocket 모듈을 통해서 STOMP를 제공하고 있다.


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/subscribe");
        registry.setApplicationDestinationPrefixes("/publish");
    }
}

백엔드에 구현한 웹소켓 설정 파일이다.

function connect() {
    var socket = new WebSocket('/ws-connection');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function () {
        setConnected(true);
        stompClient.subscribe('/subscribe/rooms/5', function (greeting) {
            console.log(greeting.body);
        });
    });
}

클라이언트에서는 위와 같은 방법으로 연결한다고 한다.

플레이어가 입퇴장할 때 프론트에서 소켓 연결을 관리해주면, 그 소켓 정보를 이용해 백에서 만든 메세지 컨트롤러로 소켓 간 실시간 통신을 할 수 있는 것 같다.

이제 메세지가 오면 같은 연결 소켓의 유저들에게 메세지를 전달해주는 ChatController를 구현할 예정이다.

Integration

프론트, ml 파트와 인테그레이션 작업을 해서 방 생성 API가 제대로 작동하는지 확인했다.