<aside> <img src="/icons/bookmark_purple.svg" alt="/icons/bookmark_purple.svg" width="40px" />
목차
</aside>
Nest.js와 Gateway를 처음 사용해보며 겪은 방황을 정리하였습니다. 해당 글은 Nest.js와 socket.io의 코드를 포함하고 있습니다.
해당 데코레이터가 어떠한 메타데이터를 설정하는지는 이전 글에서 살펴보았습니다. 그러므로 오늘은 @WebSocketGateway
를 사용한 경우 어떻게 웹소켓 연걸 정보를 처리하는지 확인해 보겠습니다.
const app = await NestFactory.create(AppModule);
해당 코드가 동작하면 NestApplication을 생성하게 됩니다.
const { SocketModule } = optionalRequire(
'@nestjs/websockets/socket-module',
() => require('@nestjs/websockets/socket-module'),
);
NestApplication 상단에는 위와 같은 코드가 존재합니다.
export function optionalRequire(packageName: string, loaderFn?: Function) {
try {
return loaderFn ? loaderFn() : require(packageName);
} catch (e) {
return {};
}
}
만약 loaderFn이 존재하면 해당 함수를 동작시키고, 없다면 명시한 패키지를 가져옵니다. 명시한 패키지가 없더라도 빈 객체를 반환하여 문제가 없게 만듭니다. 즉 '있으면 가져오고, 없으면 말고'의 코드가 되겠습니다.
프로젝트에서 '@nestjs/websockets' 종속성을 추가한 경우, 해당 코드를 통해 '@nestjs/websockets/socket-module'의 SocketModule을 불러오게 됩니다.
public async init(): Promise<this> {
if (this.isInitialized) {
return this;
}
this.applyOptions();
await this.httpAdapter?.init();
const useBodyParser =
this.appOptions && this.appOptions.bodyParser !== false;
useBodyParser && this.registerParserMiddleware();
await this.registerModules(); // 여기서 모듈을 불러옵니다.
await this.registerRouter();
await this.callInitHook();
await this.registerRouterHooks();
await this.callBootstrapHook();
this.isInitialized = true;
this.logger.log(MESSAGES.APPLICATION_READY);
return this;
}
init 과정에서 모듈을 불러옵니다.
public async registerModules() {
this.registerWsModule();
...
}
public registerWsModule() {
if (!this.socketModule) {
return;
}
this.socketModule.register(
this.container,
this.config,
this.graphInspector,
this.appOptions,
this.httpServer,
);
}
해당 과정을 통해 SocketModule의 register가 호출되는군요.
SocketModule 코드를 살펴보겠습니다.
public register(
container: NestContainer,
applicationConfig: ApplicationConfig,
graphInspector: GraphInspector,
appOptions: TAppOptions,
httpServer?: THttpServer,
) {
this.applicationConfig = applicationConfig;
this.appOptions = appOptions;
this.httpServer = httpServer;
const contextCreator = this.getContextCreator(container);
const serverProvider = new SocketServerProvider(
this.socketsContainer,
applicationConfig,
);
this.webSocketsController = new WebSocketsController(
serverProvider,
applicationConfig,
contextCreator,
graphInspector,
this.appOptions,
);
const modules = container.getModules();
modules.forEach(({ providers }, moduleName: string) =>
this.connectAllGateways(providers, moduleName),
);
}