[숏폼 프로젝트] SSE를 통한 알림 기능 구현

Manta·2024년 11월 30일
0

숏폼

목록 보기
4/7

NestJS를 사용하여 실시간 알림 시스템을 구축하는 방법을 소개하려 합니다.
이 글에서는 SSE(Server-Sent Events)를 활용하여 클라이언트와 서버 간의 실시간 통신을 구현하고, 알림 스트리밍 및 과거 알림 조회 기능을 다룹니다.

알림 시스템 아키텍처

  1. 실시간 알림 스트리밍: 특정 사용자가 이벤트를 받을 때마다 실시간으로 알림 전송.

  2. 과거 알림 조회: 사용자가 놓친 알림을 DB에서 가져와 조회.

  3. 알림 업데이트: 사용자가 읽은 알림의 상태를 업데이트.

  • NestJS: 서버 프레임워크.
  • TypeORM: 데이터베이스 ORM.
  • RxJS: 비동기 데이터 스트리밍.
  • SSE (Server-Sent Events): 클라이언트-서버 간 단방향 실시간 통신.
  • EventEmitter2: 이벤트 기반 통신.

1. 컨트롤러 구성

NotificationController는 클라이언트 요청을 처리하고, NotificationService와의 인터페이스 역할을 합니다.

@Sse('stream')
stream(@UserInfo() user: UserEntity): Observable<MessageEvent> {
  console.log(`SSE 요청 수신 for userId: ${user.id}`);
  return this.notificationService.getNotificationStream(user.id).pipe(
    map((message: string) => {
      return { data: { message } } as MessageEvent;
    }),
  );
}
  • 클라이언트는 GET /notifications/stream으로 SSE 연결을 설정합니다.
  • Observable을 사용하여 알림 이벤트를 실시간으로 스트리밍합니다.

2. 서비스 구현

NotificationService는 알림 생성, 관리 및 스트리밍 로직을 담당합니다.

async emitNotification(message: string, videoId: number) {
  const foundChannel = await this.channelRepository.findOne({
    where: { video: { id: videoId } },
    relations: ['user'],
  });

  if (!foundChannel || !foundChannel.user) {
    throw new NotFoundException('해당 사용자를 찾을 수 없습니다.');
  }

  const userId = foundChannel.user.id;

  const notification = this.notificationRepository.create({ userId, message });
  const savedNotification = await this.notificationRepository.save(notification);

  this.eventEmitter.emit(`notification:${userId}`, {
    message,
    id: savedNotification.id,
  });
}
  • 특정 비디오와 연결된 사용자를 찾아 알림 생성 후 저장.
  • EventEmitter2로 사용자 ID에 대한 이벤트를 발행.

SSE 스트림 생성

getNotificationStream(userId: number): Observable<any> {
  return new Observable<any>((subscriber) => {
    const handler = (data: { message: string; id: number }) => {
      subscriber.next(data);
    };

    this.eventEmitter.on(`notification:${userId}`, handler);

    return () => {
      this.eventEmitter.off(`notification:${userId}`, handler);
    };
  });
}
  • 특정 사용자 ID에 대한 SSE 스트림 생성
  • 이벤트 발생 시 데이터가 클라이언트로 전송

3. SSE란?

SSE (Server-Sent Events)는 서버가 클라이언트에 실시간 데이터를 단방향으로 보낼 수 있도록 하는 웹 표준입니다.
웹소켓과 달리 서버에서만 데이터를 푸시할 수 있으며, 다음과 같은 특징이 있습니다:

  • 단방향 스트림: 서버 → 클라이언트.
  • 간단한 설정: 클라이언트에서 EventSource로 간단히 구현 가능.
  • HTTP 기반: 별도 프로토콜 설정이 필요 없음.
profile
공부할게 너무 만타🫠

0개의 댓글