[SSA] 서버 SSE 기능 구현

2025. 5. 11. 20:40·SSA/Back

SSA의 알림 시스템 설계: SSE + FCM

SSA는 오프라인 강의 일정 스케줄링 서비스입니다.

 

강사가 강의 일정을 등록하거나 수정하면, 학생은 전체 강의 목록 또는 강사 이름, 강의명을 통해 강의를 검색하고 수강 신청할 수 있습니다.

이후, 강사는 수강 신청 알림을 받게 되고, 신청을 수락 또는 거절할 수 있습니다.

이 과정에서 학생 역시 수락/거절 결과에 대한 알림을 받게 됩니다.

 

 

 

SSE 란 ?

Server-Sent-Event의 약자로, 서버에서 클라이언트로 실시간 이벤트를 전달하는 웹 기술입니다.

  • 연결 시작:
    • 클라이언트에서 HTTP 프로토콜을 통해 요청
    • 서버는 text/event-stream 이라는 content-type으로 응답
    • 이후 client / server 간 데이터 파이프라인이 형성되어 연결
    • 서버에서 데이터 발행 때마다 데이터 반환
  • 연결 종료:
    • 서버는 모든 이벤트가 종료되면 연결 종료.
    • 클라이언트는 서버로부터 data: [Done] 메시지를 받으면 연결 종료 확인

event-stream 이란 ?

위 그림에서 Event Response에 담겨서 전송되는 데이터가 하나의 'event'입니다.

 

이벤트 스트림은 여러 이벤트로 구성되며, 각 이벤트는 다음과 같은 형식을 갖고 있습니다.

  • data → 이벤트의 데이터
  • event → 이벤트의 이름 (옵션)
  • id → 이벤트의 ID (옵션)
  • retry → 재연결 시간(ms) (옵션)

 

 

 

 

왜 FCM과 SSE를 함께 사용할까?

강사와 학생은 항상 온라인 상태가 아닙니다.
따라서 접속 여부에 따라 적절한 알림 전달 방식을 선택해야 합니다.

상황 기술 이유
사용자가 웹 브라우저에서 사용 중일 때 SSE 서버와 연결 유지로 빠른 실시간 알림 제공, 즉시 알림 수신 가능
사용자가 오프라인 상태일 때 FCM 앱이 꺼져 있어도 푸시 전송 가능, 앱 사용자에게 놓치지 않는 알림 보장

 

  • SSE(Server-Sent Events)는 클라이언트와 서버 간에 지속적인 연결을 유지하면서, 서버에서 실시간 이벤트를 클라이언트로 자동 푸시합니다.
  • FCM(Firebase Cloud Messaging)은 클라이언트와의 연결 없이도 백그라운드 또는 오프라인 상태의 기기에 푸시 알림을 전송할 수 있습니다.

 

 

이 두 가지를 결합하면,
접속 중 사용자는 실시간 SSE 알림을, 미접속 사용자는 FCM 푸시를 통해 알림을 받을 수 있어 효율적인 알림 시스템을 구축할 수 있습니다.

 

 

 

SSE의 연결 유지 문제와 해결 방안

SSE를 사용할 때 발생할 수 있는 두 가지 주요 문제가 있습니다:

  1. 사용자가 접속 중인데 연결이 끊기는 문제
  2. 사용자가 미접속 중인데 연결이 끊기지 않는 문제

1. 접속 중인데 연결이 끊기는 문제 → Heartbeat 메시지로 해결

  • 프록시, 게이트웨이, 브라우저 등은 유휴 연결을 일정 시간 후 자동으로 끊습니다.
  • 예) AWS API Gateway는 30초 이상 데이터가 없으면 연결 종료
  • 이를 방지하기 위해 10초마다 heartbeat 메시지를 전송하여 연결 상태를 유지합니다.

2. 미접속인데 연결이 끊기지 않는 문제 → Redis + TTL로 해결

  • 클라이언트가 브라우저 탭을 닫거나, 네트워크가 끊기면 서버에서 이를 감지하기 어렵습니다.
  • SSE 메시지 전송 시 예외가 발생하면, 해당 사용자의 SSE emitter를 제거하고 Redis 구독도 해지합니다.
  • 추가로, Redis에 online:{memberId} 형태의 키를 TTL(예: 30초)로 저장해두고, heartbeat 전송 시 TTL을 갱신합니다.
  • heartbeat나 메시지 전송 실패로 TTL이 만료되면, 사용자가 오프라인으로 판단됩니다.

 

 

 

알림 전략

  1. 사용자가 접속 중이면 (Redis 기준 online)
    • SSE로 알림 전송
    • 전송 실패 시 FCM으로 대체
    • heartbeat를 통해 연결 유지 및 Redis TTL 갱신
  2. 사용자가 미접속 중이면 (Redis TTL 만료 또는 전송 실패)
    • FCM을 통해 푸시 전송
    • FCM 송신 실패 시 재시도 로직 수행

SSE 메시지 형식 예시

data: This is a test message.
event: custom-event
id: 12345
retry: 10000
  • data: 전송할 메시지 내용
  • event: 이벤트 이름 (선택)
  • id: 이벤트 식별자 (선택)
  • retry: 연결이 끊겼을 때 재연결 시간(ms) (선택)

 

 

 

최종적으로 사용자의 접속 상태에 따라 SSE와 FCM을 적절히 조합하여

  • 실시간 반응성과
  • 오프라인 알림 누락 방지
  • 필요시에 연결 지속/해제 선택으로 네트워크 리소스 낭비 최소화

와 같은 이점을 얻을 수 있습니다.

 

'SSA > Back' 카테고리의 다른 글

[SSA] 500명 알림 발송 6.4초 -> 0.27초, 카프카 컨슈머 병렬 처리 적용기  (3) 2025.08.28
[SSA] 수강 기능 및 알림 기능을 한 곳에서 처리하면 발생할 수 있는 문제  (1) 2025.07.19
[SSA] 서버 FCM 기능 구현  (1) 2025.05.04
[SSA] 강의 도메인  (0) 2025.05.04
[SSA] 회원 도메인  (0) 2025.05.04
'SSA/Back' 카테고리의 다른 글
  • [SSA] 500명 알림 발송 6.4초 -> 0.27초, 카프카 컨슈머 병렬 처리 적용기
  • [SSA] 수강 기능 및 알림 기능을 한 곳에서 처리하면 발생할 수 있는 문제
  • [SSA] 서버 FCM 기능 구현
  • [SSA] 강의 도메인
하가네
하가네
  • 하가네
    하 렌
    하가네
  • 전체
    오늘
    어제
    • 분류 전체보기 (128) N
      • Computer Science (27)
        • 운영체제 (7)
        • 데이터통신 (10)
        • 자료구조 (4)
        • 논리회로 (0)
        • 확률 및 통계 (0)
        • 데이터베이스 (2)
        • AI소프트웨어 (3)
        • 컴퓨터네트워크 (1)
      • Design (5) N
        • OOP - 객체 지향 프로그래밍 (3) N
        • DDD - 도메인 주도 개발 (데이터베이스 주도 .. (0)
        • EDA - 이벤트 기반 아키텍처 (1)
        • MSA - 마이크로서비스 아키텍처 (0)
        • ADD - AI 주도 개발 (1)
      • Language (2)
        • Java (0)
        • TypeScript (2)
      • Framework (12)
        • Spring (9)
        • NestJS (3)
      • Engine (3)
        • Elasticsearch (1)
        • GraphQL + Apollo Federation (2)
      • Plugin - Extension (1)
        • VS Code (1)
        • IntelliJ (0)
      • Tips (2)
        • 터미널 명령어 (1)
        • 우분투 명령어 에러 (1)
      • SSA (26)
        • Front (1)
        • Back (23)
        • DB (1)
        • 기획 (1)
      • CNU SW 아카데미 (43)
        • 1주차 (5)
        • 2주차 (5)
        • 3주차 (2)
        • 4주차 (1)
        • 5주차 (3)
        • 6주차 (2)
        • 7주차 (0)
        • 8주차 (2)
        • 9주차 (14)
        • 10주차 (0)
        • 11주차 (1)
        • 12주차 (0)
        • 13주차 (2)
        • 14주차 (2)
        • 15주차(최종 프로젝트) (3)
        • 최종 프로젝트 이후 (1)
      • 모각코 (6)
        • 2023 동계 (6)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    ci/cd
    개발자경험(DX)
    DX(DeveloperExperience)
    생산성
    ESLint
    프론트엔드/백엔드
    Typescript
    Husky
    릴리스엔지니어링
    lint-staged
    아키텍처
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.
하가네
[SSA] 서버 SSE 기능 구현
상단으로

티스토리툴바