- Nest.js从零开始学习
- Nest.js概述
- 环境搭建
- 基本概念
- 依赖注入(Dependency Injection)
- 中间件与管道
- 路由与请求处理
- Nest.js 框架异常处理
- Nest.js 框架数据库操作
- Nest.js 框架认证与授权
- Nest.js 框架 WebSockets 与实时通信
- Nest.js 框架 GraphQL 支持
- Nest.js 框架微服务架构
- Nest.js 框架测试
- Nest.js 框架性能优化与安全
- Nest.js 项目实战:创建一个完整的用户管理应用
Nest.js 框架 WebSockets 与实时通信
class WebSocketsWebSockets 是一种网络通信协议,允许在客户端和服务器之间建立持久的连接,实现实时数据传输。Nest.js 提供了强大的支持来构建基于 WebSockets 的实时应用。本文将详细介绍如何在 Nest.js 中使用 WebSockets,包括如何创建实时应用,覆盖所有相关属性和方法。
1. WebSocket 模块概述
Nest.js 内置了对 WebSocket 的支持,通过 @nestjs/websockets
模块,可以轻松创建 WebSocket 服务器和客户端。它支持多种 WebSocket 库,例如 Socket.IO、ws 等。
2. 安装依赖
首先,我们需要安装 @nestjs/websockets
和 socket.io
(如果使用 Socket.IO):
npm install @nestjs/websockets socket.io
3. 创建 WebSocket 模块
3.1 创建 WebSocket Gateway
在 Nest.js 中,WebSocket Gateway 是处理 WebSocket 事件的类。我们将创建一个简单的聊天应用示例。
创建一个 chat.gateway.ts
文件:
import {
WebSocketGateway,
WebSocketServer,
SubscribeMessage,
MessageBody,
OnGatewayInit,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
@WebSocketGateway({
cors: {
origin: '*', // 允许所有来源的请求
},
})
export class ChatGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
@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(@MessageBody() data: { sender: string; content: string }) {
console.log('Received message:', data);
this.server.emit('message', data); // 广播消息给所有连接的客户端
}
}
在这个 Gateway 中,我们实现了以下功能:
- onGatewayInit:在 WebSocket 服务器初始化后执行。
- onGatewayConnection:处理客户端连接。
- onGatewayDisconnect:处理客户端断开连接。
- handleMessage:处理消息事件,并将接收到的消息广播给所有连接的客户端。
3.2 创建 Chat Module
接下来,我们需要创建一个聊天模块,以便将我们的 Gateway 注册到应用中。在 chat.module.ts
中:
import { Module } from '@nestjs/common';
import { ChatGateway } from './chat.gateway';
@Module({
providers: [ChatGateway],
})
export class ChatModule {}
3.3 更新 App Module
将 ChatModule 添加到根模块 app.module.ts
中:
import { Module } from '@nestjs/common';
import { ChatModule } from './chat/chat.module';
@Module({
imports: [ChatModule],
})
export class AppModule {}
4. 创建前端客户端
为了测试 WebSocket,我们需要创建一个简单的前端客户端。可以使用 HTML 和 JavaScript 来实现。
4.1 创建 HTML 页面
创建一个 index.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Chat</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<h1>WebSocket Chat</h1>
<input id="username" placeholder="Enter your name" />
<input id="message" placeholder="Enter a message" />
<button id="sendBtn">Send</button>
<ul id="messages"></ul>
<script>
const socket = io('http://localhost:3000');
document.getElementById('sendBtn').onclick = () => {
const username = document.getElementById('username').value;
const message = document.getElementById('message').value;
socket.emit('message', { sender: username, content: message });
document.getElementById('message').value = ''; // 清空输入框
};
socket.on('message', (data) => {
const li = document.createElement('li');
li.textContent = `${data.sender}: ${data.content}`;
document.getElementById('messages').appendChild(li);
});
</script>
</body>
</html>
在这个简单的前端页面中:
- 我们创建了一个输入框用于输入用户名和消息。
- 通过 Socket.IO 连接到 WebSocket 服务器。
- 发送消息后,通过
socket.emit
发送到服务器,并通过socket.on
监听消息事件,实时更新消息列表。
5. 运行应用
确保 WebSocket 服务器和前端都在运行:
-
启动 Nest.js 应用:
npm run start
-
打开
index.html
文件(可以使用本地服务器如http-server
来托管该文件),输入用户名和消息,点击发送。 -
在不同的浏览器窗口或标签页中打开
index.html
文件,测试实时消息传递。
6. 进阶功能
6.1 添加用户身份验证
在实际应用中,我们可能需要对用户进行身份验证,可以通过 JWT 或其他方式实现。示例中我们假设用户已通过某种方式登录并获取用户名。
6.2 处理房间
WebSocket 支持房间的概念,允许用户加入特定的房间以便更好地管理消息。
@SubscribeMessage('joinRoom')
handleJoinRoom(client: Socket, room: string) {
client.join(room);
console.log(`Client ${client.id} joined room: ${room}`);
}
@SubscribeMessage('message')
handleMessage(@MessageBody() data: { sender: string; content: string; room: string }) {
this.server.to(data.room).emit('message', data); // 仅广播到特定房间
}
用户可以通过 joinRoom
事件加入特定房间,在发送消息时也可以指定房间,从而实现分组聊天。
7. 总结
通过上述步骤,我们成功实现了一个基于 Nest.js 的 WebSocket 实时聊天应用。我们创建了 WebSocket Gateway、模块,并实现了基本的消息处理和广播功能。结合简单的前端代码,我们可以实时发送和接收消息。
- WebSocket Gateway:处理连接、消息和广播。
- Socket.IO:简化了 WebSocket 的使用,使得事件驱动的编程变得简单。
- 模块化设计:将聊天功能封装在一个独立的模块中,便于管理和扩展。
通过学习 WebSockets 和 Nest.js,我们能够为应用添加实时通信能力,这对于聊天应用、通知系统等场景非常重要。进一步的扩展可以包括用户身份验证、房间管理、消息历史记录等功能,以满足更复杂的需求。