스프링부트로 웹소켓(WebSocket)을 구현하는 기본적인 방법을 살펴보자.
웹소켓은 서버와 클라이언트가 양방향 통신을 할 수 있도록 지원하는 기술이다. 일반 HTTP 통신은 클라이언트가 요청(request)을 보내면 서버가 응답(response)을 보내고 연결이 종료되는 일방향적이고 단방향적인 흐름이라면, 웹소켓은 연결이 한 번 맺어지면 양방향으로 데이터를 계속 주고받을 수 있는 연결 상태가 유지된다.
스프링부트에서는 WebSocket을 쉽게 사용할 수 있도록 지원하고 있다. 지금부터 스프링부트를 이용해 간단한 웹소켓을 연결하는 방법과 기본적인 흐름을 살펴보자.
웹소켓 통신 흐름 간단 정리
웹소켓 통신 흐름은 크게 다음과 같다.
- 클라이언트가 서버에 WebSocket 연결을 요청한다.
- 서버가 요청을 수락하고 연결을 맺는다.
- 연결된 후 클라이언트와 서버는 양방향으로 데이터를 전송할 수 있다.
- 클라이언트 또는 서버 중 한쪽이 연결을 종료하면 연결이 닫힌다.
프로젝트 환경설정
먼저 스프링부트 프로젝트를 만든 뒤, 웹소켓 의존성을 추가하자.
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을 브라우저에서 열면 다음과 같은 흐름이 나타난다.
- 클라이언트가 웹소켓 서버에 연결 요청
- 연결 수립 후 클라이언트는 "안녕하세요 서버!" 메시지를 전송
- 서버는 받은 메시지를 콘솔에 출력 후, "서버 응답: 안녕하세요 서버!"를 클라이언트에 전송
- 클라이언트는 받은 메시지를 콘솔에 출력
마치며
지금까지 스프링부트로 웹소켓을 연결하는 방법과 기본적인 흐름을 간단히 정리해봤다.
웹소켓은 실시간 채팅이나 알림 기능 등 실시간으로 데이터를 교환할 필요가 있는 기능에서 특히 유용하다. 실제 환경에서는 세션 관리, 에러 핸들링, 보안 등 다양한 부분을 고려해야 하지만, 우선은 위의 흐름과 코드로 기초를 다지고 점점 고도화하면 된다.
'Back-End' 카테고리의 다른 글
| 금융기관 API에서 사용하는 Signed JWT + RFC8785 메시지 서명 구조 정리 (0) | 2026.02.25 |
|---|---|
| jstat로 JVM 메모리 모니터링: 실무용 해석 가이드 (3) | 2025.08.12 |
| 웹소켓 정리 (1) | 2025.05.06 |
| 실시간 데이터 처리를 위한 RabbitMQ 설계와 웹소켓 연동 (1) | 2025.05.02 |
| exitCode (0) | 2024.11.21 |