웹소켓이 서버랑 계속 연결되어있다는 보장을 어떻게 판단하나? + 웹소켓 데이터가 유실된다면?

ssongyi·2025년 7월 12일
0

Java/Spring TIL

목록 보기
26/27

Q. 웹소켓이 서버랑 계속 연결되어있다는 보장을 어떻게 판단하나?

웹소켓은 기본적으로 TCP 기반의 지속적인 연결 상태를 유지하지만, 연결이 실제로 살아있는지는 네트워크 단절, 브라우저 종료, 서버 다운 등 다양한 원인으로 예기치 않게 끊길 수 있기 때문에, 명시적으로 연결 상태를 확인하는 로직이 필요합니다.

이를 확인하는 방법으로는 대표적으로 다음과 같은 방식들을 사용합니다

🔧 웹소켓 - 서버 연결 보장 판단 방법

1. 클라이언트 → 서버 핑/퐁(Ping/Pong) 또는 하트비트(heartbeat) 주기 설정

  • 일정 주기로 클라이언트가 서버에 Ping 메시지를 보내고, 서버는 Pong으로 응답합니다.

  • 응답이 없으면 연결이 끊어진 것으로 간주하여 재연결을 시도합니다.

  • 예: STOMP에서는 heart-beat 설정이 대표적입니다.

2. 서버 → 클라이언트 측에서도 Ping 가능 (서버가 주기적 메시지 전송)

  • 서버가 주기적으로 상태 확인 메시지를 보내고, 클라이언트 응답 여부로 판단합니다.

3. WebSocket의 onclose, onerror 이벤트 핸들링

  • 클라이언트에서는 onclose, onerror 이벤트 리스너를 통해 연결 종료 여부를 감지합니다.

  • 서버 측에서도 세션 상태를 추적하며, 종료된 세션을 정리하거나 reconnect 로직을 유도할 수 있습니다.

4. 서버에서 세션 타임아웃 감지 및 제거 로직 구현

  • 서버에서 일정 시간 동안 메시지를 받지 않으면 해당 세션을 종료하는 방식으로 끊긴 연결을 정리합니다.

✅ 마무리 정리:

따라서, 웹소켓 연결이 살아있다는 보장을 위해서는 단순히 연결 여부를 믿는 것이 아니라, 클라이언트와 서버 양쪽에서 정기적인 하트비트나 핑/퐁 메시지를 통해 연결 상태를 능동적으로 확인하고, 끊겼을 때 재연결 로직까지 구현하는 것이 중요하다고 생각합니다.


Q. 웹소켓 데이터가 유실되면 어떻게 하나요? 보완 방법이 있을까요?

웹소켓은 기본적으로 TCP 기반 프로토콜이라 패킷 자체가 유실되는 경우는 거의 없습니다.
하지만 실제 애플리케이션에서는 다음과 같은 상황에서 메시지 유실이 발생할 수 있습니다:

  • 클라이언트가 연결 종료 직전 메시지를 못 받았을 때
  • 서버가 비정상 종료되었을 때
  • 브라우저 탭이 갑자기 닫혔을 때
  • 네트워크 지연/단절 후 자동 복구가 안 된 경우

이런 실질적인 "메시지 유실"을 방지하기 위한 보완 방법으로는 다음과 같은 전략을 사용합니다

🔧 보완 방법

1. 메시지 ID / 시퀀스 번호 부여

  • 각 메시지에 고유 ID나 순번(sequence)을 부여해서 클라이언트가 받은 마지막 메시지를 기억하고,
  • 재연결 시 해당 이후 메시지만 요청하도록 처리합니다.
  • → 이 방식은 서버에 메시지 로그(혹은 메시지 큐)가 저장되어 있어야 합니다.

2. 재전송 요청 (Resend on reconnect)

  • 연결이 끊긴 후 재연결되었을 때, 클라이언트는 서버에 "마지막으로 받은 메시지 ID"를 보내고, 누락된 메시지를 요청합니다.

  • → 이 기능을 위해 서버에 단기 메시지 캐시 또는 로그 저장소가 필요합니다. (ex. Redis, Kafka, DB 등)

3. ACK(확인 응답) 기반 전송 보장

  • 클라이언트가 메시지를 수신하면 "받았다"는 ACK 메시지를 서버에 전송하고,

  • 서버는 ACK가 올 때까지 재전송 시도 또는 대기 상태 유지.

  • → 실시간성보다 신뢰성 위주인 시스템에서 사용 (ex. 금융 채팅, 알림 등)

4. Fallback 기능 추가 (WebSocket + HTTP 병행)

  • 유실된 메시지를 REST API 등을 통해 다시 받아올 수 있도록 구성 (CQRS 구조 활용)

  • 예: 과거 채팅 메시지 또는 알림 내역을 WebSocket과 별도로 HTTP로 조회

5. 브라우저 저장소 활용

  • 클라이언트 측에서 수신한 메시지를 IndexedDB, localStorage 등에 일시 저장해두고 복구 시 활용

✅ 마무리 정리:

요약하자면, 웹소켓 자체는 TCP 기반이라 유실 확률이 낮지만, 클라이언트 또는 서버의 상태 변화, 네트워크 문제 등으로 인해 애플리케이션 수준의 메시지 유실은 언제든 발생할 수 있습니다.
이를 보완하기 위해서는 메시지 ID + 재전송 + ACK + 캐시 저장소 조합을 통해 신뢰성을 높이는 전략이 중요하다고 생각합니다.

0개의 댓글