Nestjs高级进阶WebSocket实现实时双向通信
在NestJS中实现WebSocket双向通信时遇到几个问题:
- 如何正确配置Gateway模块,客户端始终无法成功连接,端口和路径确认无误但依然返回404错误?
- 使用@SubscribeMessage处理消息时,如何区分不同的客户端并实现定向消息推送?当前广播消息正常,但需要针对特定用户发送数据。
- WebSocket连接频繁断开重连,心跳机制该如何在NestJS中优雅实现?尝试了socket.io的pingInterval但未见效。
- 生产环境部署后出现跨域问题,虽然开发阶段配置了CORS,但Nginx反向代理后仍然报错,正确的代理配置参数是什么?
- 如何结合JWT实现WebSocket的身份验证?尝试在握手阶段验证token,但客户端无法正常传递Authorization头信息。
3 回复
在NestJS中实现WebSocket的实时双向通信非常优雅。首先,你需要安装必要的依赖:
npm install @nestjs/websockets socket.io
创建一个WebSocket服务类,并使用@WebSocketGateway()
装饰器标记它:
import { WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server } from 'socket.io';
@WebSocketGateway()
export class ChatGateway {
@WebSocketServer() server: Server;
handleConnection(client: any) {
console.log(`Client connected: ${client.id}`);
}
handleDisconnect(client: any) {
console.log(`Client disconnected: ${client.id}`);
}
sendMessage(client: any, message: string) {
this.server.emit('message', message);
}
}
然后,在模块文件中导入该服务并启用它:
import { Module } from '@nestjs/common';
import { ChatGateway } from './chat.gateway';
@Module({
providers: [ChatGateway],
})
export class AppModule {}
最后,你可以通过客户端连接到服务器,并发送/接收消息。例如,前端可以使用Socket.IO客户端:
const socket = io('http://localhost:3000');
socket.on('connect', () => {
console.log('Connected to server');
});
socket.on('message', (msg) => {
console.log('Received:', msg);
});
socket.emit('message', 'Hello Server');
这样,你就可以实现简单的实时双向通信了。
在NestJS中实现WebSocket的实时双向通信非常方便。首先需要安装依赖@nestjs/websockets
和socket.io
:
npm install @nestjs/websockets socket.io
然后创建一个WebSocket服务类:
import { OnModuleInit, OnModuleDestroy, WebSocketGateway } from '@nestjs/websockets';
@WebSocketGateway()
export class ChatGateway implements OnModuleInit, OnModuleDestroy {
private clients: any[] = [];
async onModuleInit() {
console.log('ChatGateway初始化');
}
async onModuleDestroy() {
console.log('ChatGateway销毁');
}
handleConnection(client: any) {
this.clients.push(client);
console.log(`客户端已连接:${client.id}`);
}
handleDisconnect(client: any) {
this.clients = this.clients.filter(c => c.id !== client.id);
console.log(`客户端已断开:${client.id}`);
}
sendMessageToAll(message: string) {
this.clients.forEach(client => client.emit('receiveMessage', message));
}
}
在main.ts
中启用WebSocket:
const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(newWsAdapter(app));
await app.listen(3000);
这样就实现了简单的实时消息推送功能,客户端通过emit
发送消息,服务端可以监听并广播给所有客户端。
NestJS高级进阶:WebSocket实现实时双向通信
WebSocket简介
WebSocket是一种在单个TCP连接上进行全双工通信的协议,非常适合需要实时双向通信的应用场景,如聊天应用、实时通知、在线游戏等。
NestJS中的WebSocket实现
NestJS提供了两种WebSocket实现方式:
- 使用原生WebSocket (
@nestjs/websockets
) - 使用Socket.io (
@nestjs/platform-socket.io
)
1. 使用Socket.io实现
// websocket.gateway.ts
import { SubscribeMessage, WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
@WebSocketGateway({
cors: {
origin: '*', // 实际项目中应配置具体域名
}
})
export class WebsocketGateway {
@WebSocketServer()
server: Server;
afterInit(server: Server) {
console.log('WebSocket server initialized');
}
handleConnection(client: Socket) {
console.log(`Client connected: ${client.id}`);
}
handleDisconnect(client: Socket) {
console.log(`Client disconnected: ${client.id}`);
}
@SubscribeMessage('message')
handleMessage(client: Socket, payload: any): string {
console.log('Received message:', payload);
this.server.emit('message', payload); // 广播给所有客户端
return 'Message received';
}
}
2. 模块注册
// websocket.module.ts
import { Module } from '@nestjs/common';
import { WebsocketGateway } from './websocket.gateway';
@Module({
providers: [WebsocketGateway]
})
export class WebsocketModule {}
高级功能
1. 房间功能
@SubscribeMessage('joinRoom')
handleJoinRoom(client: Socket, room: string) {
client.join(room);
return `Joined room ${room}`;
}
@SubscribeMessage('roomMessage')
handleRoomMessage(client: Socket, { room, message }) {
this.server.to(room).emit('roomMessage', message);
}
2. 认证与中间件
// websocket.gateway.ts
@WebSocketGateway({
middlewares: [WsAuthMiddleware]
})
export class WebsocketGateway {}
3. 适配器
// main.ts
import { IoAdapter } from '@nestjs/platform-socket.io';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new IoAdapter(app));
await app.listen(3000);
}
客户端连接示例
// 前端代码
const socket = io('http://localhost:3000');
socket.on('connect', () => {
console.log('Connected to server');
});
socket.emit('message', { text: 'Hello from client' });
socket.on('message', (data) => {
console.log('Received message:', data);
});
性能优化
- 使用Redis适配器实现多实例扩展
- 启用HTTP长轮询作为降级方案
- 合理设置心跳间隔
通过以上方式,你可以在NestJS中构建高性能的实时双向通信应用。