我的项目中有多个@WebsocketGateways
,其中一个实现了OnGatewayConnection
生命周期挂钩。似乎每个网关都被调用一次生命周期挂钩,即使只有一个实现它们也是如此。这是默认行为,错误还是我做错了什么?
CommonGateway
@WebSocketGateway()
export class CommonGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server;
users: number = 0;
handleConnection() {
this.users++;
console.log('USER CONNECTED: ', this.users);
}
handleDisconnect() {
this.users--;
console.log('USER Disconnected: ', this.users);
}
}
DatesGateway
import {
WebSocketGateway,
SubscribeMessage,
WsResponse,
} from '@nestjs/websockets';
import { CommonService } from 'src/common/common.service';
@WebSocketGateway()
export class DatesGateway {
constructor(private readonly commonService: CommonService) {}
@SubscribeMessage('dates-now')
onNow(client): Promise<WsResponse<Date>> {
return Promise.resolve(this.commonService.now).then(now => ({
event: 'dates-now',
data: now,
}));
}
}
控制台屏幕截图
可以找到一个演示该问题的小仓库here
谢谢
答案 0 :(得分:1)
我在创建多个网关后才遇到此问题。我正在使用@nestjs/platform-ws
和@nestjs/websockets
的 6.10.1 版本。
使用以下解决方案,将创建一个WebSocket服务器,并且handleConnection
将被调用一次(根据需要)。 handleDisconnect
事件始终(正确)触发一次。重要的是要注意:
platform-ws
适配器时,名称空间可以是唯一的或相同的。platform-socket.io
适配器时,名称空间必须相同。EADDRINUSE
和UnhandledPromiseRejectionWarning: Error: The HTTP/S server is already being used by another WebSocket server
错误。MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added. Use emitter.setMaxListeners() to increase limit
警告。我仍然需要研究这个。app.gateway.ts
@WebSocketGateway(8080, {namespace: 'foo'})
export class AppGateway implements OnGatewayConnection, OnGatewayDisconnect {
constructor() {}
public handleConnection(): void {}
public handleDisconnect(): void {}
@SubscribeMessage('app:event')
public handleGet(): WsResponse<string> {
return {
event: 'app:event',
data: 'foobar'
};
}
}
user.gateway.ts
@WebSocketGateway(8080, {namespace: 'foo'})
export class UserGateway {
constructor() {}
@SubscribeMessage('user:event')
public handleGet(): WsResponse<string> {
return {
event: 'user:event',
data: 'foobar'
};
}
}
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { WsAdapter } from '@nestjs/platform-ws';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
await app.listen(80);
}
bootstrap();
欢迎对此有更多见识。
答案 1 :(得分:0)
这是因为您已在模块中多次声明了网关,而不是在主模块中将其声明为导出并在另一个模块中将其导入。我也遇到类似的问题,发现删除导出模块或将模块设置为全局装饰器模块都有帮助。在继续使用该模块之前,请研究该模块的全局装饰器:https://docs.nestjs.com/modules
答案 2 :(得分:0)
我找到了解决方案。 显然,这是NestJS中的错误(?),如果您根本不定义任何名称空间,则会为所有网关启动多个名称空间。然后是每个连接事件。
解决方案是在每个WebSocketGateways
@WebSocketGateway({namespace: 'yournamespace'})
并像这样连接到客户端中的服务器:
io.connect('http://localhost:4200/yournamespace');