Nestjs教程构建WebSocket服务器

在Nestjs中构建WebSocket服务器时,如何正确处理连接和断开事件?使用@WebSocketGateway时,发现客户端断开后服务器没有触发handleDisconnect方法,该如何排查和解决?另外,如何实现房间/分组功能,让特定客户端订阅不同频道?官方文档的示例比较简单,有没有更完整的实战案例可以参考?

3 回复
  1. 安装依赖

    npm install [@nestjs](/user/nestjs)/websockets [@nestjs](/user/nestjs)/platform-ws socket.io
    
  2. 创建模块与服务

    nest g module chat
    nest g service chat/chat
    
  3. 配置WebSocket模块
    chat模块的app.module.ts中添加:

    import { Module } from '[@nestjs](/user/nestjs)/common';
    import { ChatGateway } from './chat.gateway';
    
    [@Module](/user/Module)({
      providers: [ChatGateway],
    })
    export class AppModule {}
    
  4. 创建WebSocket网关
    chat目录下创建chat.gateway.ts

    import { WebSocketGateway, WebSocketServer } from '[@nestjs](/user/nestjs)/websockets';
    import { Server, Socket } from 'socket.io';
    
    [@WebSocketGateway](/user/WebSocketGateway)()
    export class ChatGateway {
      @WebSocketServer() server: Server;
    
      handleConnection(client: Socket) {
        console.log(`Client connected: ${client.id}`);
      }
    
      handleDisconnect(client: Socket) {
        console.log(`Client disconnected: ${client.id}`);
      }
    
      sendMessage(client: Socket, data: any) {
        this.server.emit('newMessage', data);
      }
    }
    
  5. 启动应用
    运行npm run start:dev,WebSocket服务器即可运行。

  6. 客户端测试
    使用Socket.IO客户端连接并发送消息。


要使用NestJS搭建WebSocket服务器,可以按照以下步骤:

  1. 初始化项目:npm i -g [@nestjs](/user/nestjs)/cli,然后运行 nest new project-name

  2. 安装WebSocket依赖:npm install [@nestjs](/user/nestjs)/websockets socket.io.

  3. 创建WebSocket模块:nest generate module chatnest generate controller chat --no-module

  4. chat.controller.ts中设置WebSocket连接逻辑:

    import { Controller, Get, WebSocketServer } from '[@nestjs](/user/nestjs)/common';
    import { Server, Socket } from 'socket.io';
    
    [@Controller](/user/Controller)('chat')
    export class ChatController {
      @WebSocketServer() server: Server;
    
      @Get()
      findAll(): string {
        return 'This route will serve as the entry point for the chat app.';
      }
    
      afterInit(server: Server) {
        console.log('Server initialized');
      }
    
      handleConnection(client: Socket) {
        console.log('Client connected:', client.id);
      }
    
      handleDisconnect(client: Socket) {
        console.log('Client disconnected:', client.id);
      }
    
      sendMessage(client: Socket, data: any) {
        this.server.emit('message', data);
      }
    }
    
  5. 修改app.module.ts,导入WsModule并将ChatController绑定到WebSocket端点:

    import { Module } from '[@nestjs](/user/nestjs)/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { WsModule } from '[@nestjs](/user/nestjs)/websockets';
    
    [@Module](/user/Module)({
      imports: [WsModule],
      controllers: [AppController, ChatController],
      providers: [AppService],
    })
    export class AppModule {}
    
  6. 启动应用,客户端可以通过/ws路径连接到WebSocket服务。

NestJS WebSocket 服务器构建教程

NestJS提供了强大的WebSocket支持,主要通过两种方式实现:

  1. 使用内置的WebSocket模块
  2. 使用Socket.io集成

方法一:使用内置WebSocket模块

1. 安装必要依赖

npm install @nestjs/websockets @nestjs/platform-socket.io

2. 创建网关(相当于WebSocket控制器)

// src/events/events.gateway.ts
import { WebSocketGateway, WebSocketServer, SubscribeMessage } from '@nestjs/websockets';
import { Server } from 'socket.io';

@WebSocketGateway({
  cors: {
    origin: '*',
  },
})
export class EventsGateway {
  @WebSocketServer()
  server: Server;

  @SubscribeMessage('message')
  handleMessage(client: any, payload: any): string {
    console.log(payload);
    this.server.emit('message', payload); // 广播给所有客户端
    return 'Message received';
  }
}

3. 注册网关模块

// src/events/events.module.ts
import { Module } from '@nestjs/common';
import { EventsGateway } from './events.gateway';

@Module({
  providers: [EventsGateway]
})
export class EventsModule {}

方法二:使用Socket.io集成

1. 安装Socket.io

npm install socket.io @nestjs/platform-socket.io

2. 创建适配器

// src/socket-io.adapter.ts
import { IoAdapter } from '@nestjs/platform-socket.io';

export class SocketIoAdapter extends IoAdapter {
  createIOServer(port: number, options?: any): any {
    return super.createIOServer(port, {
      ...options,
      cors: {
        origin: '*',
        methods: ['GET', 'POST'],
      },
    });
  }
}

3. 在主模块中使用适配器

// src/main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useWebSocketAdapter(new SocketIoAdapter(app));
  await app.listen(3000);
}

客户端连接示例

// 客户端代码
const socket = io('http://localhost:3000');

socket.on('connect', () => {
  console.log('Connected to server');
});

socket.emit('message', { text: 'Hello server!' });

socket.on('message', (data) => {
  console.log('Received:', data);
});

WebSocket在NestJS中非常灵活,你可以轻松实现实时聊天、通知推送等功能。

回到顶部