Spring Boot로 구현하는 실시간 채팅 시스템 - Part 1: 기본 구조 이해하기
Spring Boot와 WebSocket, STOMP 프로토콜, Redis를 활용하여 실시간 채팅 시스템 구현
1. HTTP vs WebSocket
HTTP 통신의 특징과 한계
HTTP 통신의 특징과 한계 기존의 웹 애플리케이션에서 주로 사용하는 HTTP 통신은 다음과 같은 특징이 있습니다.
1. 비연결성(Connectionless)
- 클라이언트가 요청을 보내면 서버가 응답을 하고 바로 연결을 종료
- 실시간 통신에는 부적합
2. 단방향 통신
- 클라이언트의 요청이 있어야만 서버가 응답 가능
- 서버에서 클라이언트로 먼저 데이터를 보낼 수 없음
3. 무상태성(Stateless)
- 서버가 클라이언트의 상태를 저장하지 않음
- 매 요청마다 필요한 모든 정보를 담아서 전송해야 함
WebSocket의 필요성
채팅과 같은 실시간 양방향 통신이 필요한 서비스에서는 HTTP 통신만으로는 한계가 있습니다.
이러한 한계를 극복하기 위해 WebSocket이 등장했습니다.
WebSocket의 장점
- 양방향 실시간 통신 가능
- 한번 연결을 맺으면 계속 유지 (연결 비용 감소)
- 서버에서 클라이언트로 능동적인 데이터 전송 가능
- 실시간 데이터 전송에 최적화
HTTP 통신과 WebSocket 통신에 대해 알고 구현하기전 STOMP 프로토콜의 이해가 필요합니다.
2. STOMP
STOMP(Simple Text Oriented Messaging Protocol)는 WebSocket 위에서 동작하는 메시징 프로토콜입니다.
주요 특징
- 간단한 텍스트 기반 메시징 프로토콜
- pub/sub(발행/구독) 구조 지원
- 메시지 브로커를 통한 메시지 전달
Pub/Sub 구조 이해하기
STOMP는 발행자(Publisher)와 구독자(Subscriber) 패턴을 사용합니다
1. 구독자(Subscriber)
- 특정 주제(topic)를 구독
- 해당 주제로 들어오는 메시지를 수신
2. 발행자(Publisher)
- 특정 주제로 메시지를 발행
- 구독자들에게 메시지가 전달됨
3. 메시지 브로커
- 발행된 메시지를 구독자들에게 전달하는 중간 역할
- 메시지 전달을 관리하고 제어
3. 프로젝트 의존성 추가
스프링부트 프로젝트속 Gradle에 해당 의존성 추가
WebSocket 클라이언트 의존성
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.webjars:webjars-locator-core'
implementation 'org.webjars:sockjs-client:1.5.1'
implementation 'org.webjars:stomp-websocket:2.3.4'

하단 두개는 메시지를 Nosql인 Redis를 이용하여 저장할때 쓰이는 의존성
필자처럼 Redis를 사용시 추가하기
스프링부트 application.yml 설정추가
spring:
redis:
host: localhost
port: 6379
password: 1234
내부적으로 Redis를 설치하여 진행합니다.
AWS에서 지원하는 Redis나 자체 EC2서버속 Redis를 설치하여 사용한다면,
host에 Redis( 서버 )의 아이피를 넣어주시면됩니다.
포트는 기본적으로 Redis는 6379포트를 사용합니다.
password는 Redis 세팅에서 패스워드를 설정한 것을 넣어주시면됩니다.
4. WebSocket 기본 설정
프로젝트속 파일구조에서 Config/WebSocketConfig 생성
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 구독자 경로 설정 - 구독자들은 해당 경로를 구독하고 메시지를 받음
registry.enableSimpleBroker("/sub");
// 발행자 경로 설정 - 발행자들은 해당 경로로 메시지를 발행
registry.setApplicationDestinationPrefixes("/pub");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// WebSocket 연결 엔드포인트 설정
registry.addEndpoint("/ws-stomp")
.setAllowedOriginPatterns("*")
.withSockJS();
}
}
설정 상세 설명
- @EnableWebSocketMessageBroker
- WebSocket 서버 활성화
- STOMP 사용 설정
- 메시지 브로커 설정
- /sub: 구독 요청을 처리할 prefix
- /pub: 메시지 발행 요청을 처리할 prefix
- 엔드포인트 설정
- /ws-stomp: 웹소켓 연결 주소
- setAllowedOriginPatterns("*"): CORS 설정
- withSockJS(): WebSocket을 지원하지 않는 브라우저를 위한 대체 옵션
메시지 라우팅 과정
- 클라이언트가 /pub/chat/message로 메시지 발행
- 서버의 @MessageMapping 메서드에서 메시지 처리
- 처리된 메시지는 /sub/chat/room/{roomId}를 구독 중인 클라이언트들에게 전달
지금까지 채팅 시스템 구현을 위한 기본적인 WebSocket과 STOMP에 대해 알아보았으며,
다음 포스팅에서는 실제 채팅방과 메시지 도메인 모델을 구현하고, Redis를 연동하는 방법에 대해 알아보도록 하겠습니다.
- 채팅방과 메시지 도메인 모델 구현
- Redis 연동 및 설정
- 실시간 메시지 처리 로직 구현
'Spring Boot' 카테고리의 다른 글
| [Spring Boot] 스프링부트에서 WebSocket, STOMP를 이용한 채팅기능 구현하기 (2) - 도메인 모델과 Redis 연동 (3) | 2024.11.29 |
|---|---|
| 단위 테스트에서 private 메소드 테스트가 필요한가? (4) | 2024.10.28 |
| @requiredargsconstructor @autowired 차이 (3) | 2024.10.06 |