Back-End

웹소켓 정리 2

isTrue 2025. 5. 7. 23:02
반응형

스프링부트로 웹소켓(WebSocket)을 구현하는 기본적인 방법을 살펴보자.

웹소켓은 서버와 클라이언트가 양방향 통신을 할 수 있도록 지원하는 기술이다. 일반 HTTP 통신은 클라이언트가 요청(request)을 보내면 서버가 응답(response)을 보내고 연결이 종료되는 일방향적이고 단방향적인 흐름이라면, 웹소켓은 연결이 한 번 맺어지면 양방향으로 데이터를 계속 주고받을 수 있는 연결 상태가 유지된다.

스프링부트에서는 WebSocket을 쉽게 사용할 수 있도록 지원하고 있다. 지금부터 스프링부트를 이용해 간단한 웹소켓을 연결하는 방법과 기본적인 흐름을 살펴보자.

 

웹소켓 통신 흐름 간단 정리

웹소켓 통신 흐름은 크게 다음과 같다.

  1. 클라이언트가 서버에 WebSocket 연결을 요청한다.
  2. 서버가 요청을 수락하고 연결을 맺는다.
  3. 연결된 후 클라이언트와 서버는 양방향으로 데이터를 전송할 수 있다.
  4. 클라이언트 또는 서버 중 한쪽이 연결을 종료하면 연결이 닫힌다.

 

프로젝트 환경설정

먼저 스프링부트 프로젝트를 만든 뒤, 웹소켓 의존성을 추가하자.

build.gradle

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

 

 

WebSocket 설정 클래스 작성

웹소켓을 활성화하고 핸들러를 등록할 설정 클래스를 작성한다.

WebSocketConfig.java

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/ws/chat")
                .setAllowedOrigins("*");
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyWebSocketHandler();
    }
}
  • @EnableWebSocket: 스프링부트에서 웹소켓을 활성화한다.
  • /ws/chat: 웹소켓 연결을 요청할 주소다.
  • setAllowedOrigins("*"): 모든 도메인에서 접근할 수 있도록 허용한다. (보안상 실제 운영 환경에서는 구체적인 도메인을 설정해주자.)

 

WebSocketHandler 작성

WebSocketHandler는 웹소켓 연결과 데이터 통신을 관리하는 역할을 한다.

MyWebSocketHandler.java

public class MyWebSocketHandler extends TextWebSocketHandler {

    // 연결이 성립되었을 때 호출
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("웹소켓 연결됨: " + session.getId());
    }

    // 클라이언트로부터 메시지를 받았을 때 호출
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("받은 메시지: " + message.getPayload());

        // 받은 메시지를 그대로 다시 보내기 (에코)
        session.sendMessage(new TextMessage("서버 응답: " + message.getPayload()));
    }

    // 연결이 끊어졌을 때 호출
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("웹소켓 종료됨: " + session.getId());
    }
}
  • afterConnectionEstablished: 웹소켓 연결이 성립되면 실행된다.
  • handleTextMessage: 메시지를 받으면 처리할 로직을 작성한다.
  • afterConnectionClosed: 연결이 종료되었을 때 실행된다.

 

간단한 HTML로 테스트하기

프론트엔드에서 연결을 확인할 수 있도록 간단한 HTML을 작성해 테스트하자.

test-websocket.html

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket 테스트</title>
</head>
<body>
    <script>
        const socket = new WebSocket('ws://localhost:8080/ws/chat');

        socket.onopen = function() {
            console.log("웹소켓 연결됨!");
            socket.send("안녕하세요 서버!");
        };

        socket.onmessage = function(event) {
            console.log("서버로부터 메시지 받음:", event.data);
        };

        socket.onclose = function() {
            console.log("웹소켓 연결 종료됨!");
        };

        socket.onerror = function(error) {
            console.error("웹소켓 오류:", error);
        };
    </script>
</body>
</html>

 

 

실행 및 결과 확인

스프링부트 서버를 실행한 뒤, HTML을 브라우저에서 열면 다음과 같은 흐름이 나타난다.

  • 클라이언트가 웹소켓 서버에 연결 요청
  • 연결 수립 후 클라이언트는 "안녕하세요 서버!" 메시지를 전송
  • 서버는 받은 메시지를 콘솔에 출력 후, "서버 응답: 안녕하세요 서버!"를 클라이언트에 전송
  • 클라이언트는 받은 메시지를 콘솔에 출력

 

마치며

지금까지 스프링부트로 웹소켓을 연결하는 방법과 기본적인 흐름을 간단히 정리해봤다.

웹소켓은 실시간 채팅이나 알림 기능 등 실시간으로 데이터를 교환할 필요가 있는 기능에서 특히 유용하다. 실제 환경에서는 세션 관리, 에러 핸들링, 보안 등 다양한 부분을 고려해야 하지만, 우선은 위의 흐름과 코드로 기초를 다지고 점점 고도화하면 된다.

반응형