首页 > 解决方案 > 如何将动态端口传递给 NestJS 中的 Websockets-gateway?

问题描述

我想从 NestJS 的配置中动态设置 Websockets-gateway 端口。下面是我的websockets-gateway代码。

import { WebSocketGateway } from '@nestjs/websockets';

const WS_PORT = parseInt(process.env.WS_PORT);

@WebSocketGateway(WS_PORT)
export class WsGateway {
  constructor() {
    console.log(WS_PORT);
  }
}

但 WS_PORT 始终为 NaN。

这是我的引导函数 insdie main.ts :

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { cors: false });
  const configService = app.get(ConfigService);
  initAdapters(app);
  await app.listen(configService.get(HTTP_PORT), () => {
    console.log('Listening on port ' + configService.get(HTTP_PORT));
  });
}

下面是我的app.module.ts

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: './src/config/dev.env',
      isGlobal: true,
    }),
    RedisModule,
    SocketStateModule,
    RedisPropagatorModule,
    JwtModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        secret: configService.get<string>(JWT_SECRET_KEY),
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AppController],
  providers: [WsGateway, AppService],
})
export class AppModule {}

我在网关构造函数中放置了一个控制台日志以打印“WS_PORT”的值,但它始终是 NaN。

[Nest] 13252  - 10/04/2021, 5:05:34 PM     LOG [NestFactory] Starting Nest application...
NaN

提前致谢。

标签: websocketconfigurationnestjsdecorator

解决方案


我找不到将动态数据添加到装饰器的方法。因此,为了能够动态选择端口和其他配置,我必须:

  • 为 socket-io 创建一个适配器:
  • 告诉 NestJs 使用新的适配器

SocketIoAdapter.ts

import { INestApplicationContext } from '@nestjs/common';
import { IoAdapter } from '@nestjs/platform-socket.io';
import { ServerOptions } from 'socket.io';
import { ConfigService } from '@nestjs/config';

export class SocketIoAdapter extends IoAdapter {
constructor(
  private app: INestApplicationContext,
  private configService: ConfigService,
) {
  super(app);
}

createIOServer(port: number, options?: ServerOptions) {
  port = this.configService.get<number>('SOCKETIO.SERVER.PORT');
  const path = this.configService.get<string>('SOCKETIO.SERVER.PATH');
  const origins = this.configService.get<string>(
    'SOCKETIO.SERVER.CORS.ORIGIN',
  );
  const origin = origins.split(',');
  options.path = path;
  options.cors = { origin };
  const server = super.createIOServer(port, options);
  return server;
}
}

现在,您需要编辑main.ts以使用适配器

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ConfigService } from '@nestjs/config';
import { SocketIoAdapter } from './socket-io/socket-io.adapter';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService);
  const hosts = configService.get<string>('CORS.HOST');
  const hostsArray = hosts.split(',');
  app.enableCors({
    origin: hostsArray,
    credentials: true,
  });
//Here you use the adapter and sent the config service
  app.useWebSocketAdapter(new SocketIoAdapter(app, configService));
  await app.listen(4300);
}
bootstrap();


在这种情况下,我设置了端口和 cors 来源,这里是 conf 文件的示例(使用 .env) env.local

SOCKETIO.SERVER.PORT=4101
SOCKETIO.SERVER.PATH=
SOCKETIO.SERVER.CORS.ORIGIN=http://localhost:4200,http://localhost.com:8080

这里是配置服务Config Service NestJs的链接


推荐阅读