我正在尝试在我的 Nestjs 应用程序中设置一个 WebSocket。 env 和 package 版本如下:
Node: v18.17.0
@nestjs/core: "^9.0.0"
@nestjs/platform-socket.io: "^10.3.8"
我创建了多个文件来实现: chat.gateway.ts:
import {
MessageBody,
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
OnGatewayInit,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Logger, OnModuleInit } from '@nestjs/common';
import { Server, Socket } from 'socket.io';
@WebSocketGateway(4040)
export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect, OnModuleInit {
@WebSocketServer() server: Server;
private logger: Logger = new Logger('ChatGateway');
onModuleInit() {
this.logger.log('ChatGateway Module has been initialized');
}
@SubscribeMessage('newMessage')
handleMessage(@MessageBody() body: any): void {
this.logger.log(`Message received: ${JSON.stringify(body)}`);
this.server.emit('message', body);
}
afterInit(server: Server): void {
console.log('WebSocket server initialized');
}
handleConnection(client: Socket, ...args: any[]): void {
this.logger.log(`Client connected: ${client.id}`);
}
handleDisconnect(client: Socket): void {
this.logger.log(`Client disconnected: ${client.id}`);
}
}
chat.gateway.module.ts:
import { Module } from '@nestjs/common';
import { ChatGateway } from './chat.gateway';
@Module({
providers: [ChatGateway],
})
export class ChatGatewayModule {}
app.module.ts:
@Module({
imports: [
...otherModules,
ChatGatewayModule
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {
constructor(private readonly logger: LoggerService) {
mongoose.set('debug', (collectionName: any, method: any, query: any, doc: any) => {
logger.info(`Mongoose: ${collectionName}.${method}(${JSON.stringify(query)}, ${JSON.stringify(doc)})`);
});
this.logger.log("App is running...");
}
private onApplicationShutdown(signal: string) {
this.logger.log("App is shutting down...");
}
}
我创建了一个简单的 HTML 文件来检查连接:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Test</title>
</head>
<body>
<h1>WebSocket Test</h1>
<script>
const socket = new WebSocket('ws://localhost:4040/chat');
socket.onopen = function(event) {
console.log('WebSocket connection established');
socket.send(JSON.stringify({ message: 'Hello Server!' }));
};
socket.onmessage = function(event) {
console.log('Message from server:', event.data);
};
socket.onclose = function(event) {
console.log('WebSocket connection closed');
};
socket.onerror = function(error) {
console.error('WebSocket error:', error);
};
</script>
</body>
</html>
我通过在本地运行
npm run start:dev
来运行 Nestjs 应用程序。它打印 LOG [ChatGateway] ChatGateway Module has been initialized
,但不打印 WebSocket server initialized
方法中的 afterInit
。
然后我使用 Google Chrome 在 HTML 页面上尝试连接,但失败并显示 WebSocket 连接到
'ws://localhost:4040/chat' failed:
消息。
我应该做什么来解决? 谢谢。
如果你想访问某个路由,例如 ws://localhost:4040/chat(在 websockets 术语中称为命名空间),你需要更改你的
@WebSocketGateway(4040)
到
@WebSocketGateway(4040, { namespace: 'chat' })
至于为什么 afterInit() 不起作用,我发现另一篇文章可能有用。
tl;dr:我认为你应该将nestJS核心库升级到10.3.8,或者将你的@nestjs/platform-socket.io降级到9.0.0(你的核心nestJS库)。所以基本上两者应该是相同的版本。