WebSocket with Spring Boot

By | 2024년 10월 13일
Table of Contents

WebSocket with Spring Boot

Spring Boot 에서 WebSocket 서버를 구성하는 방법을 설명합니다.

의존성 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation "org.springframework.boot:spring-boot-starter-thymeleaf"
    implementation 'org.springframework.boot:spring-boot-starter-websocket'
}

WebSocketHandler

@Slf4j
@Component
public class WebSocketHandler extends TextWebSocketHandler {

    private static final ConcurrentHashMap<String, WebSocketSession> CLIENTS = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        System.out.println("Connected : " + session.getId());
        CLIENTS.put(session.getId(), session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        System.out.println("Disconnected : " + session.getId());
        System.out.println("Disconnect status code : " + status.getCode());
        CLIENTS.remove(session.getId());
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        System.out.println("Sender : " + session.getId());
        System.out.println("Received message : " + message.getPayload());
        CLIENTS.forEach((key, value) -> {
            try {
                value.sendMessage(message);
            } catch (IOException e) {
                log.error("Exception: {}", e.getMessage());
            }
        });
    }
}

WebSocketConfig

@Configuration
@EnableWebSocket
@RequiredArgsConstructor
public class WebSocketConfig implements WebSocketConfigurer {

    private final WebSocketHandler webSocketHandler;

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

클라이언트

클라이언트는 JavaScript 로 생성합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>웹소켓</title>
</head>
<body>
<h1>웹소켓 테스트</h1>

<button id="btn_send">메시지 전송</button>
<button id="btn_close">연결 끊기</button>
</body>
<script>
    // ====================================================
    // connect
    const webSocket = new WebSocket("ws://localhost:8080/ws");

    // ====================================================
    // on open
    webSocket.onopen = () => {
        console.log("웹소켓서버와 연결 성공");
    };

    // ====================================================
    // receive message
    webSocket.onmessage = function (event) {
        console.log(`서버 웹소켓에게 받은 데이터: ${event.data}`);
    }

    // ====================================================
    // on close
    webSocket.onclose = function() {
        console.log("서버 웹소켓 연결 종료");
    }

    // ====================================================
    // on error
    webSocket.onerror = function(event) {
        console.log(event)
    }

    let count = 1;
    document.getElementById("btn_send").onclick = function() {
        if(webSocket.readyState === webSocket.OPEN) {
            // ============================================
            // send
            webSocket.send(`증가하는 숫자를 보냅니다 => ${count}`);
            count++;
        }else{
            alert("연결된 웹소켓 서버가 없습니다.");
        }
    }

    document.getElementById("btn_close").onclick = function() {
        if(webSocket.readyState === webSocket.OPEN) {
            // ============================================
            // close
            webSocket.close();
        }else{
            alert("연결된 웹소켓 서버가 없습니다.");
        }
    }
</script>
</html>

답글 남기기