基础环境准备
在构建WebSocket通信系统前,需完成基础环境搭建。首先通过npm安装核心依赖包:
npm install --save @nestjs/websockets @nestjs/platform-socket.io socket.io
这些包分别提供WebSocket网关支持、Socket.IO平台适配及底层通信能力。其中@nestjs/websockets是NestJS官方提供的WebSocket模块,socket.io作为底层通信库,两者结合可实现跨浏览器兼容的实时通信。
核心网关实现
WebSocket通信的核心逻辑集中在Gateway类中,以下通过分步骤实现完整功能:
1. 创建网关类
import {WebSocketGateway,WebSocketServer,SubscribeMessage,MessageBody,ConnectedSocket,OnGatewayInit,OnGatewayConnection,OnGatewayDisconnect} from '@nestjs/websockets';import { Server, Socket } from 'socket.io';@WebSocketGateway({namespace: '/chat',cors: {origin: '*', // 生产环境应配置具体域名methods: ['GET', 'POST']}})export class ChatGateway implementsOnGatewayInit,OnGatewayConnection,OnGatewayDisconnect{@WebSocketServer()server: Server;// 初始化回调afterInit(server: Server) {console.log('WebSocket Server Initialized', server.engine.clientsCount);}// 连接建立处理handleConnection(client: Socket) {console.log(`Client connected: ${client.id}`);// 可在此处实现认证逻辑}// 连接断开处理handleDisconnect(client: Socket) {console.log(`Client disconnected: ${client.id}`);}}
关键配置说明:
namespace:实现逻辑隔离,不同命名空间可承载不同业务场景cors:跨域配置,开发阶段可设为通配符,生产环境需严格限制- 生命周期接口:
OnGatewayInit等接口提供标准化的事件处理机制
2. 消息处理实现
通过@SubscribeMessage装饰器定义消息处理器:
@SubscribeMessage('sendMessage')handleMessage(@MessageBody() data: { user: string; message: string },@ConnectedSocket() client: Socket) {console.log(`Received message from ${data.user}: ${data.message}`);// 广播消息给所有客户端(除发送者)client.broadcast.emit('receiveMessage', {...data,timestamp: new Date().toISOString()});// 若需包含发送者,使用:// this.server.emit('receiveMessage', {...data});}
消息处理最佳实践:
- 数据结构标准化:建议定义DTO类进行数据校验
- 错误处理:添加try-catch块捕获异常
- 性能优化:避免在处理器中执行耗时操作
模块集成与注册
创建独立模块管理WebSocket相关依赖:
import { Module } from '@nestjs/common';import { ChatGateway } from './chat.gateway';@Module({providers: [ChatGateway],exports: [ChatGateway] // 如需在其他模块使用})export class ChatModule {}
在主模块中导入该模块:
import { Module } from '@nestjs/common';import { ChatModule } from './chat/chat.module';@Module({imports: [ChatModule],// ...其他配置})export class AppModule {}
客户端集成实现
浏览器端实现分为连接建立、事件监听和消息发送三部分:
1. 基础连接
const socket = io('http://localhost:3000/chat', {transports: ['websocket'], // 优先使用WebSocketreconnection: true, // 自动重连reconnectionAttempts: 5, // 重试次数reconnectionDelay: 1000 // 重试间隔});
2. 事件处理
// 连接状态监听socket.on('connect', () => {console.log('Connection established', socket.id);});socket.on('disconnect', (reason) => {console.log('Disconnected:', reason);});// 消息接收处理socket.on('receiveMessage', (data) => {const messageElement = document.createElement('div');messageElement.innerHTML = `<strong>${data.user}:</strong> ${data.message}`;document.getElementById('messages').appendChild(messageElement);});
3. 消息发送
document.getElementById('send-btn').addEventListener('click', () => {const user = '当前用户'; // 实际应从登录状态获取const message = document.getElementById('message-input').value;socket.emit('sendMessage', { user, message }, (ack) => {console.log('Server acknowledgement:', ack);});});
高级功能扩展
1. 房间管理实现
// 加入房间@SubscribeMessage('joinRoom')handleJoinRoom(@MessageBody() { roomId }: { roomId: string },@ConnectedSocket() client: Socket) {client.join(roomId);client.emit('roomJoined', { roomId });}// 房间内广播@SubscribeMessage('roomMessage')handleRoomMessage(@MessageBody() { roomId, ...data }: { roomId: string; user: string; message: string },@ConnectedSocket() client: Socket) {client.to(roomId).emit('roomMessageReceived', data);}
2. 认证中间件
@WebSocketGateway({middleware: [authMiddleware] // 自定义中间件})export class SecureChatGateway {// ...其他配置}// 中间件示例const authMiddleware = (socket: Socket, next: (err?: any) => void) => {const token = socket.handshake.auth.token;if (verifyToken(token)) {return next();}next(new Error('Unauthorized'));};
生产环境优化建议
- 连接管理:实现心跳机制检测连接状态
- 消息限流:防止客户端频繁发送消息
- 负载均衡:使用Redis适配器实现多实例通信
- 监控告警:集成日志服务跟踪连接状态
- 安全加固:配置HTTPS、设置合理的CORS策略
完整项目结构
src/├── chat/│ ├── chat.gateway.ts│ ├── chat.module.ts│ └── dto/ # 数据传输对象├── app.module.ts└── main.ts
通过本文的实践指导,开发者可以系统掌握NestJS中WebSocket通信的实现方法,从基础环境搭建到高级功能扩展形成完整知识体系。建议在实际项目中结合具体业务场景进行功能定制,并持续关注框架更新以引入新的优化特性。