Nestjs高级进阶WebSocket实现实时双向通信

在NestJS中实现WebSocket双向通信时遇到几个问题:

  1. 如何正确配置Gateway模块,客户端始终无法成功连接,端口和路径确认无误但依然返回404错误?
  2. 使用@SubscribeMessage处理消息时,如何区分不同的客户端并实现定向消息推送?当前广播消息正常,但需要针对特定用户发送数据。
  3. WebSocket连接频繁断开重连,心跳机制该如何在NestJS中优雅实现?尝试了socket.io的pingInterval但未见效。
  4. 生产环境部署后出现跨域问题,虽然开发阶段配置了CORS,但Nginx反向代理后仍然报错,正确的代理配置参数是什么?
  5. 如何结合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/websocketssocket.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实现方式:

  1. 使用原生WebSocket (@nestjs/websockets)
  2. 使用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);
});

性能优化

  1. 使用Redis适配器实现多实例扩展
  2. 启用HTTP长轮询作为降级方案
  3. 合理设置心跳间隔

通过以上方式,你可以在NestJS中构建高性能的实时双向通信应用。

回到顶部