본문 바로가기

TYPESCRIPT

NESTJS- Subscriber

Nestjs에서 Subscriber는 이벤트 핸들러를 정의하는 클래스입니다. Subscriber클래스는 특정 이벤트가 발생할 때 이를 수신하고 처리하는 역할을 수행한다. 비동기적인 이벤트 처리를 가능하게합니다.

 

📍 비동기 적인 이벤트 처리란!

Subscriber의 비동기적인 이벤트 처리는 이벤트를 구독하는 Subscriber(구독자)가 이벤트를 비동기적으로 처리하는 방식을 의미합니다. Subscriber는 특정 이벤트를 구독하고, 해당 이벤트가 발생했을 때 비동기적으로 처리하는 로직을 갖추고 있습니다.

일반적으로 이벤트 기반 시스템에서 Subscriber는 이벤트 발행자(Publisher)로부터 이벤트를 받아들이고, 필요한 작업을 수행하는 역할을 합니다. 이벤트 발행자는 이벤트를 발생시키고, 이를 구독 중인 Subscriber에게 알립니다. 이 때, Subscriber는 비동기적으로 이벤트를 처리할 수 있습니다.

비동기적인 이벤트 처리 방식은 Subscriber가 이벤트를 받아들인 후 즉시 처리하지 않고, 다른 작업을 수행하거나 다른 이벤트를 처리하는 동안에도 블로킹하지 않고 동시에 다른 작업을 수행할 수 있습니다. 이는 시스템의 응답성과 성능을 향상시키는 데 도움이 됩니다.

 

 

 

로그인이 일어나면 접속정보를 저장하는 이벤트입니다.

 

예제코드 

import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { LoginEvent } from './login-event.interface';

export interface LoginConnectedEvent {
  userId: string;
  loginTime: Date;
  ipAddress: string;
}

@Injectable()
export class LoginSubscriber {
  @OnEvent('user.login')
  handleLoginEvent(event: LoginEvent) {
    // 접속 정보를 저장하는 이벤트 생성
    const connectedEvent: LoginConnectedEvent = {
      userId: event.userId,
      loginTime: event.loginTime,
      ipAddress: event.ipAddress, // 로그인 시점의 IP 주소
    };
    
 	// LoginHistory 저장
    await this.loginHistoryRepository.create(loginHistory);

    // 저장된 접속 정보를 활용하여 추가 작업 수행
    console.log(`User ${connectedEvent.userId} connected from ${connectedEvent.ipAddress}`);
    // 접속 정보를 데이터베이스에 저장하거나 다른 처리를 수행할 수 있습니다.
  }
}

 

Event Emitter 등록 Subscriber사용하려면 해당 Subscriber를 Event Emitter에 등록해야 함. 이를 위해선 모듈단에서 Event Emitter 를 import하고 등록해야합니다.

import { Module } from '@nestjs/common';
import { OrderSubscriber } from './order.subscriber';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [EventEmitterModule.forRoot()],
  providers: [LoginSubscriber],
})
export class AppModule {}
import { Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { LoginEvent } from './login-event.interface';

@Injectable()
export class LoginService {
  constructor(private readonly eventEmitter: EventEmitter2) {}

  async loginUser(userId: string, loginTime: Date, ipAddress: string) {
    // 로그인 처리 로직

    // LoginEvent 생성
    const loginEvent: LoginEvent = {
      userId,
      loginTime,
      ipAddress,
    };

    // LoginEvent 발생 시킴
    this.eventEmitter.emit('user.login', loginEvent);
  }
}

'TYPESCRIPT' 카테고리의 다른 글

Interface VS Type  (0) 2023.11.29
ELASTIC  (1) 2023.05.19