저장을 습관화
NestJS - 네임스페이스와 생명주기(Lifecycle) 메모 본문
1. 네임스페이스
http 연결 방식의 경우 엔드포인트를 통해 api를 나누었다.
예를 들어
users/signup, users/login, users/update의 API를 가진 컨트롤러, 서비스 등의 내용이 담긴
users.module.ts
post/write, post/update, post/delete의 API를 가진 컨트롤러, 서비스 등의 내용이 담긴
posts.module.ts
이렇게 users와 post 두 개의 모듈로 나누어 유지 보수성을 향상시킬 수 있었다.
웹소켓을 사용한 양방향 통신 방식에서는 네임스페이스를 통해 모듈을 나눌 수 있다.
- chats.gateway.ts - 소켓의 게이트웨이, 클라이언트와 서버 간의 소켓 통신을 처리하는 엔드포인트
// 중략
import { WebSocketGateway } from '@nestjs/websockets';
@WebSocketGateway({ namespace: 'chattings' })
export class ChatsGateway {
// 중략
}
웹 소켓 게이트웨이에서 namespace가 'chattings'라고 선언하였다.
- script.js
const socket = io('/chattings'); // socket.io의 메소드를 사용하기 위한 준비이며,
// 네임스페이스는 '/chattings'가 된다.
// 중략..
const helloUser = () => {
const username = prompt('What is your name?');
socket.emit('new_user', username, (data) => {
console.log(data);
});
// 중략..
이러한 상황에서 서버와 클라이언트 간의 통신이 'chattings' 네임스페이스 안에서 이루어진다.
2. 생명주기(Lifecycle)
- chats.gateway.ts
import { Logger } from '@nestjs/common';
import {
SubscribeMessage,
WebSocketGateway,
MessageBody,
ConnectedSocket,
OnGatewayInit,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Socket } from 'socket.io';
@WebSocketGateway({ namespace: 'chattings' })
export class ChatsGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
// OnGateWayInit, OnGatewayConnection, OnGatewayDisconnect은 인터페이스이며 인터페이스는 규약이다.
// 규약에 따라 OnGatewayInit의 뒤에는 반드시 afterInit()이 와야하며,
// OnGatewayConnection의 뒤에는 반드시 handleConnection()이,
// OnGatewayDisconnect의 뒤에는 반드시 handleDisconnect()가 와야한다.
{
private logger = new Logger('chat');
constructor() {
this.logger.log('this is constructor');
}
handleDisconnect(@ConnectedSocket() socket: Socket) {
this.logger.log(`disconnected: ${socket.id}, ${socket.nsp.name}`); // nsp는 네임스페이스의 약자
}
handleConnection(@ConnectedSocket() socket: Socket) {
this.logger.log('this is connect');
this.logger.log(`connected: ${socket.id}, ${socket.nsp.name}`);
}
afterInit() {
this.logger.log('this is init');
}
// 중략..
}
nestjs에서 socket 통신을 할 때에 쓰이는 주요 lifecycle hooks에는 3가지가 있다
이 셋은 모두 인터페이스이며 규약이 정해져 있다.
onGatewayInit - 게이트웨이 클래스가 실행되었을때 제일 먼저 호출된다.
반드시 afterInit()이 뒤따라온다.
OnGatewayConnection - 통신이 연결되었을때 호출된다.
반드시 handleConnection()이 뒤따라 온다.
소켓 인스턴스를 전달인자로 사용할 수 있다.
OnGatewayDisconnect - 통신의 연결이 끊어졌을때(창 닫음, 새로고침 등) 호출된다.
반드시 handleDisconnect()가 뒤따라 온다.
소켓 인스턴스를 전달인자로 사용할 수 있다.
https://docs.nestjs.com/websockets/gateways#lifecycle-hooks
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
실행 결과
- 웹 서버 가동 시
[오후 9:41:01] Starting compilation in watch mode...
[오후 9:41:04] Found 0 errors. Watching for file changes.
[Nest] 16004 - 2023. 10. 19. 오후 9:41:05 LOG [NestFactory] Starting Nest application...
[Nest] 16004 - 2023. 10. 19. 오후 9:41:05 LOG [chat] this is constructor
[Nest] 16004 - 2023. 10. 19. 오후 9:41:05 LOG [InstanceLoader] MongooseModule dependencies initialized +1ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:05 LOG [InstanceLoader] ChatsModule dependencies initialized +0ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:05 LOG [InstanceLoader] AppModule dependencies
initialized +0ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:05 LOG [InstanceLoader] ConfigHostModule dependencies initialized +1ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:05 LOG [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:06 LOG [InstanceLoader] MongooseCoreModule dependencies initialized +509ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:06 LOG [chat] this is init
[Nest] 16004 - 2023. 10. 19. 오후 9:41:06 LOG [WebSocketsController] ChatsGateway subscribed to the "new_user" message +1ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:06 LOG [RoutesResolver] AppController {/}: +2ms[Nest] 16004 - 2023. 10. 19. 오후 9:41:06 LOG [RouterExplorer] Mapped {/, GET} route +2ms
[Nest] 16004 - 2023. 10. 19. 오후 9:41:06 LOG [NestApplication] Nest application successfully started +2ms
클래스의 생성자 constructor의 로그가 가장 먼저 찍히며
그 다음 onGatewayInit - afterInit의 로그가 찍힌다.
- 웹 페이지 접속 시
접속 후 chattings 네임스페이스의 socket.emit을 실행시킨다.
[Nest] 16004 - 2023. 10. 19. 오후 9:43:12 LOG [chat] this is connect
[Nest] 16004 - 2023. 10. 19. 오후 9:43:12 LOG [chat] connected: 5dr8aPTIAHFCySsaAAAH,
/chattings
OnGatewayConnection - handleConnection의 로그가 찍힌다.
- 웹 페이지를 닫아 연결을 끊는다.
[Nest] 16004 - 2023. 10. 19. 오후 9:43:12 LOG [chat] this is connect
[Nest] 16004 - 2023. 10. 19. 오후 9:43:12 LOG [chat] connected: 5dr8aPTIAHFCySsaAAAH,
/chattings
[Nest] 16004 - 2023. 10. 19. 오후 9:46:46 LOG [chat] disconnected: 5dr8aPTIAHFCySsaAAAH, /chattings
OnGatewayDisconnect - handleDisconnect의 로그가 찍혔다.
아래 게이트웨이에서 확인할 수 있듯
메소드 handleDisconnect, handleConnection, afterInit가 적힌 순서에 상관없이
각자의 상황에서 메소드를 실행시키며,
constructor는 클래스 자체의 생성자이기 때문에 다른 인터페이스의 메소드들보다 앞서서 실행된다.
@WebSocketGateway({ namespace: 'chattings' })
export class ChatsGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
private logger = new Logger('chat');
constructor() {
this.logger.log('this is constructor');
}
handleDisconnect(@ConnectedSocket() socket: Socket) {
this.logger.log(`disconnected: ${socket.id}, ${socket.nsp.name}`); // nsp는 네임스페이스의 약자
}
handleConnection(@ConnectedSocket() socket: Socket) {
this.logger.log('this is connect');
this.logger.log(`connected: ${socket.id}, ${socket.nsp.name}`);
}
afterInit() {
this.logger.log('this is init');
}
}
'공부 > node.js' 카테고리의 다른 글
NestJS - hot reload (0) | 2023.11.04 |
---|---|
NestJS - socket.broadcast.emit() 브로드캐스팅 방식 (0) | 2023.10.20 |
NestJS - socket.emit, socket.on 연습 기록 (0) | 2023.10.19 |
NestJS - multer를 사용하여 S3에 데이터 저장 1 (0) | 2023.10.14 |
NestJS - multer를 이용한 미디어 파일 서비스 (0) | 2023.10.09 |