如何将动态端口传递到 NestJS 中的 Websockets 网关?
How to pass a dynamic port to the Websockets-gateway in NestJS?
我想在 NestJS 的配置中动态设置 Websockets 网关端口。下面是我的 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。
这是我的 bootstrap 函数 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
提前致谢。
你试过了吗DynamicModule
?
我找不到向装饰器添加动态数据的方法。因此,为了能够动态选择端口和其他配置,我必须:
- 为 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
此处link配置服务Config Service NestJs
port = this.configService.get<number>('SOCKETIO.SERVER.PORT');
在我的例子中,我找到了它的 return 字符串(来自 .env),端口得到 'string' 但不是 'number',
但是如果把 parseInt(this.configService.get<number>('SOCKETIO.SERVER.PORT'), 10);
那么就可以了
请注意 socket-io 服务器端和客户端的端口必须相同
我想在 NestJS 的配置中动态设置 Websockets 网关端口。下面是我的 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。
这是我的 bootstrap 函数 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
提前致谢。
你试过了吗DynamicModule
?
我找不到向装饰器添加动态数据的方法。因此,为了能够动态选择端口和其他配置,我必须:
- 为 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
此处link配置服务Config Service NestJs
port = this.configService.get<number>('SOCKETIO.SERVER.PORT');
在我的例子中,我找到了它的 return 字符串(来自 .env),端口得到 'string' 但不是 'number',
但是如果把 parseInt(this.configService.get<number>('SOCKETIO.SERVER.PORT'), 10);
那么就可以了
请注意 socket-io 服务器端和客户端的端口必须相同