실시간 채팅 구현기(2) 기술 설명 및 구현 방법

2026. 4. 12. 16:25·프로젝트

이전 시간엔 실시간 채팅 서비스를 위해 어떤 기술 스택을 사용할지 선정해봤다.

이번 시간엔 이 기술들에 대해 자세히 이해해보고 어떤식으로 구현할지 얘기해보겠다.

 

실시간 채팅 서비스의 핵심은 유실없는 실시간 전송과 불안정한 네트워크 환경에서도 안정적으로 작동하는 것이다.

지난번에 선정한 주요 기술스택을 살펴보자.

 

WebSocket

클라이언트에서 서버 단방향으로 요청과 응답 그리고 연결 종료가 일어나는 HTTP와 달리 웹소켓은 양방향으로 통신할 수 있으며, HTTP에 비해 통신하는데 발생하는 오버헤드가 적다.

 

웹소켓의 동작 과정은 다음과 같다.

 

1. 클라이언트가 HTTP 프로토콜로 Handshake 요청을 한다.

GET /chat/websocket HTTP/1.1
Host: your-domain.com
Origin: http://your-domain.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: v10.stomp, v11.stomp, v12.stomp

클라이언트 → 서버 upgrade handshake 요청 예시

 

2. 서버가 요청을 받으면 HTTP Upgrade 헤더를 사용하여 웹소켓 프로토콜로 변경할 수 있도록 명시한다.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9KYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: v12.stomp

서버 → 클라이언트 upgrade handshake 응답 예시

 

3. handshake가 성공하면 통신 프로토콜을 WebSocket 프로토콜로 변환한다.

WebSocket은 일반 Socket 통신과는 달리 80, 443 포트 위에서 동작하도록 설계되었다.

즉, 별도의 포트가 필요없다.

웹소켓의 통신 프로토콜명은 ws다. ws는 HTTP에 대응하는 것이고, HTTPS는 wss를 사용해야 한다.

 

STOMP

Simple Text Oriented Message Protocol라는 이름처럼 텍스트 기반의 메시지 규격이다.

STOMP 메시지는 Command, Header, Body 세 부분으로 구성되어있다.

SEND
destination:/pub/chat/message
content-type:application/json
Authorization:Bearer eyJhbGciOiJIUzI1...

{
  "roomId": "10",
  "sender": "Poloopy",
  "message": "안녕하세요! 반갑습니다."
}^@
  • Command : CONNECT, SEND, SUBSCRIBE, MESSAGE 등 수행할 동작을 정의한다.
  • Header : 메시지 전송 경로, 권한 인증, 콘텐츠 타입 등을 정의한다.
  • Body : 실제 전송할 데이터가 들어간다.
  • ^@ : 메시지의 끝을 알리는 null octet

Spring 프레임워크에서 STOMP 메시지 프로토콜을 지원하고 있어 @MessageMapping라는 어노테이션을 통해 손쉽게 destination으로 보낼 수 있다.

 

Redis Streams

메시지 브로커 역할을 한다.

데이터 구조는 시간순으로 기록되는 로그와 같다.

Redis Streams에는 저장할 때 다음과 같은 구조로 명령을 보낸다.

[명령어] [스트림키] [ID] [필드] [값] ...

 

다음과 같은 명령어가 주로 쓰인다.

  • XADD : 메시지 발행
  • XREAD : 메시지 조회
  • XGROUP : 소비자 그룹 생성
  • XREADGROUP : 그룹 메시지 읽기
  • XACK : 처리 완료 응답
  • XPENDING : 미처리된 메시지 골라 재처리

Redis Streams에선 메시지 보장 처리를 하기 위해 XREADGROUP로 소비자가 메시지를 가져가는 순간 PEL(Pending Entries List)에 넣는다. PEL은 메시지를 가져갔지만 ACK를 아직 보내지 않은 메시지들의 리스트로 만약 소비자가 메시지를 가져갔지만 처리하지 못하고 있다면 이에 대한 처리 로직을 구현해 XPENDING으로 재처리할 수 있다.

 

 

기술스택에 대해서 정리해봤으니 이제 어떻게 구현할지에 대해서 알아보자.

실시간 채팅 서비스의 전체적인 아키텍처는 연결 - 발행 - 분산 - 수신 4단계로 이루어진다.

 

연결

채팅방에 접속하게 되면 웹소켓 연결을 시도한다.

엔드포인트를 설정하여 해당 경로로 접근하면 웹소켓 연결을 시도한다.

다음 연결 시점에 JWT 토큰을 검사하여 유효한 사용자인지 검증한다.

그리고 .withSockJS()를 활성화하여 웹소켓이 차단된 상태에서도 Polling 방식으로 실시간 통신이 이어질 수 있도록 한다.

발행

사용자가 메시지를 보내면 @MessageMapping() 컨트롤러가 인터셉트해 웹소켓 메시지를 서버에 전달해준다.

이때 보내는 메시지 규격은 STOMP이다.

Command 내용에 따라 Handler를 구현하여 다음과 같은 요청을 한다.

  • 클라이언트는 특정 방 ID를 포함한 주소를 구독한다.
  • 방에 메시지를 보낸다.

이때 구독한 대상은 메시지 브로커가 아니라 서버 애플리케이션이다.

이를 roomId별로 구분하여 Consumer Group을 만든다.

분산

단일 서버라면 바로 메시지를 뿌려줄 수 있지만, 서버가 여러대인 분산 환경에서는 다른 서버에 접속한 유저에게도 메시지를 보내야 한다. 메시지의 검증이 끝났다면 RedisTemplate을 사용하여 Redis Streams의 특정 토픽으로 XADD한다.

수신

각 서버는 Consumer Group에 속한 소비자로서 대기하다 메시지가 들어오면 읽어들인다.

서버는 읽어온 메시지의 roomId를 확인하고 해당 방을 구독하고 있던 유저들에게만 SimpMessagingTemplate을 통해 메시지를 전달한다.

클라이언트는 STOMP의 MESSAGE 프레임을 통해 화면에 새 채팅을 띄운다.

 

 

다음 시간엔 실제 코드들을 보며 코드 구현과 개발하며 생긴 이슈들과 해결 방법에 대해 작성해보겠다.

'프로젝트' 카테고리의 다른 글

실시간 채팅 구현기(3) 코드 분석  (0) 2026.04.16
실시간 채팅 구현기(1) 기술 스택 선정 및 연동(SockJS, STOMP, Redis Streams)  (0) 2026.04.12
'프로젝트' 카테고리의 다른 글
  • 실시간 채팅 구현기(3) 코드 분석
  • 실시간 채팅 구현기(1) 기술 스택 선정 및 연동(SockJS, STOMP, Redis Streams)
뽀루피
뽀루피
  • 뽀루피
    뽀루피의 개발스토리
    뽀루피
  • 전체
    오늘
    어제
    • 분류 전체보기 (83)
      • 프로젝트 (3)
      • Java (32)
        • JPA (4)
        • Spring (8)
      • FrontEnd (4)
        • JavaScript (1)
        • Flutter (3)
      • DB (4)
        • SQL (4)
      • 알고리즘 (10)
      • Git (3)
      • SSAFY (0)
      • Figma (1)
      • Notion (0)
      • Jira (0)
      • 기획 (0)
      • 네트워크 (10)
      • 우아한테크코스 (2)
      • Infra (5)
        • AWS (0)
        • Docker (3)
      • AI (1)
      • 자격증 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준
    JPA
    Jenkins
    모던 자바 인 액션
    스프링
    웹소켓
    n8n
    네트워크 기초
    자바
    java
    redis streams
    Stomp
    cloudflare
    트랜잭션
    SQL
    크래프트맨 멘탈리티
    fetch join
    Docker
    알고리즘
    네트워크
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
뽀루피
실시간 채팅 구현기(2) 기술 설명 및 구현 방법
상단으로

티스토리툴바