Nestjs教程使用Socket.IO实现实时消息推送
我在使用NestJS结合Socket.IO实现实时消息推送时遇到了一些问题。首先不太清楚如何在NestJS中正确配置Socket.IO模块,官方文档的说明比较简略。其次,我在客户端连接时总是出现404错误,不知道是不是网关配置有问题。另外想请教如何区分不同类型的实时消息,比如私聊和群聊消息该如何通过Socket.IO实现?最后,想了解在生产环境中如何优化Socket.IO的性能,比如是否需要Redis适配器?希望有经验的大佬能分享一下具体实现方案和最佳实践。
3 回复
首先安装必要的依赖:
npm install @nestjs/websockets socket.io
- 创建一个WebSocket服务模块:
nest g module chat
nest g service chat/chat
nest g controller chat/chat
- 在
chat.service.ts
中配置Socket.IO:
import { Injectable, OnModuleInit } from '@nestjs/common';
import { Server, Socket } from 'socket.io';
@Injectable()
export class ChatService implements OnModuleInit {
private server: Server;
private clients = new Map();
onModuleInit() {
this.server = new Server();
this.server.on('connection', (socket: Socket) => {
console.log(`Client connected: ${socket.id}`);
this.clients.set(socket.id, socket);
socket.on('disconnect', () => {
this.clients.delete(socket.id);
console.log(`Client disconnected: ${socket.id}`);
});
});
}
// 广播消息
broadcastMessage(message: string) {
this.clients.forEach((client) => client.emit('message', message));
}
}
- 在
chat.controller.ts
中设置路由:
import { Controller, Get, OnModuleInit } from '@nestjs/common';
import { Server, Socket } from 'socket.io';
import { ChatService } from './chat.service';
@Controller()
export class ChatController implements OnModuleInit {
constructor(private readonly chatService: ChatService) {}
onModuleInit() {
this.chatService.server.installHandlers(this);
}
@Get('broadcast')
broadcastMessage(@Query('message') message: string) {
this.chatService.broadcastMessage(message);
return { success: true };
}
}
- 最后在主应用文件
main.ts
中启用WebSocket:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Server } from 'socket.io';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const server = app.getHttpAdapter().getInstance();
const io = new Server(server);
io.on('connection', (socket) => {
console.log(`Client connected: ${socket.id}`);
});
await app.listen(3000);
}
bootstrap();
启动应用后,访问/broadcast?message=HelloWorld
即可广播消息。
要在NestJS中使用Socket.IO实现实时消息推送,首先安装必要的依赖:
npm install @nestjs/websockets socket.io
- 创建一个WebSocket服务:
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { WsGateway } from './ws.gateway';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService, WsGateway],
})
export class AppModule {}
- 定义WebSocket网关:
// ws.gateway.ts
import { WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
@WebSocketGateway()
export class WsGateway {
@WebSocketServer() server: Server;
afterInit(server: Server) {
console.log('WebSocket初始化完成');
}
handleConnection(client: Socket) {
console.log(`客户端已连接: ${client.id}`);
}
handleDisconnect(client: Socket) {
console.log(`客户端断开连接: ${client.id}`);
}
sendMessageToClient(message: string) {
this.server.emit('message', message);
}
}
- 调用发送消息:
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { WsGateway } from './ws.gateway';
@Controller()
export class AppController {
constructor(private readonly wsGateway: WsGateway) {}
@Get('send-message')
async sendMessage() {
this.wsGateway.sendMessageToClient('Hello, Client!');
return '消息已发送!';
}
}
这样就完成了简单的实时消息推送功能。客户端通过socket.on('message', callback)
接收消息。
NestJS中使用Socket.IO实现实时消息推送教程
基本设置
- 首先安装Socket.IO相关依赖:
npm install @nestjs/platform-socket.io socket.io @types/socket.io
- 创建Socket.IO网关(Gateway):
import { SubscribeMessage, WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
@WebSocketGateway({
cors: {
origin: '*', // 设置允许的客户端来源
},
})
export class EventsGateway {
@WebSocketServer()
server: Server;
afterInit(server: Server) {
console.log('Socket.IO服务器已初始化');
}
handleConnection(client: Socket) {
console.log(`客户端已连接: ${client.id}`);
}
handleDisconnect(client: Socket) {
console.log(`客户端已断开连接: ${client.id}`);
}
@SubscribeMessage('message')
handleMessage(client: Socket, payload: any): string {
console.log('收到消息:', payload);
this.server.emit('message', payload); // 广播给所有客户端
return '消息已接收';
}
}
- 在AppModule中注册网关:
import { Module } from '@nestjs/common';
import { EventsGateway } from './events.gateway';
@Module({
providers: [EventsGateway],
})
export class AppModule {}
高级功能实现
- 实现房间功能:
@SubscribeMessage('joinRoom')
handleJoinRoom(client: Socket, room: string): void {
client.join(room);
console.log(`客户端 ${client.id} 加入了房间 ${room}`);
}
@SubscribeMessage('leaveRoom')
handleLeaveRoom(client: Socket, room: string): void {
client.leave(room);
console.log(`客户端 ${client.id} 离开了房间 ${room}`);
}
// 向特定房间发送消息
sendToRoom(room: string, event: string, message: any) {
this.server.to(room).emit(event, message);
}
import { Injectable } from '@nestjs/common';
import { EventsGateway } from './events.gateway';
@Injectable()
export class ChatService {
constructor(private readonly eventsGateway: EventsGateway) {}
sendMessageToAll(message: string) {
this.eventsGateway.server.emit('message', message);
}
}
客户端连接
前端HTML示例:
<script src="https://cdn.socket.io/4.3.1/socket.io.min.js"></script>
<script>
const socket = io('http://localhost:3000');
socket.on('connect', () => {
console.log('已连接到服务器');
});
socket.on('message', (data) => {
console.log('收到消息:', data);
});
function sendMessage() {
const message = document.getElementById('message').value;
socket.emit('message', message);
}
</script>
这就是在NestJS中使用Socket.IO实现实时消息推送的基本方法。你可以根据需求扩展更多功能,如用户认证、消息持久化等。