NestJS搭建项目(二)nest+socket.io搭建简易聊天室

socket.io

首先介绍一下socket.io吧。

socket.io是一个用于实现实时通信的JavaScript库。它可以在浏览器和服务器之间实现双向通信,支持多种传输协议,如WebSocket、LongPolling、XHR等。socket.io的主要目的是为了简化实时通信在浏览器和服务器之间的实现,使得开发者可以专注于业务逻辑的实现。

socket.io的主要特点包括:

  1. 支持多种传输协议:socket.io支持WebSocket、LongPolling、XHR等传输协议,可以根据浏览器和服务器的支持情况自动选择合适的传输协议。
  2. 自动重连:socket.io会自动检测连接断开的情况,并在适当的时候尝试重新连接。
  3. 消息压缩:socket.io支持对发送的消息进行压缩,以减少传输的数据量。
  4. 错误处理:socket.io提供了丰富的错误处理机制,可以捕获并处理客户端和服务器之间的错误。
  5. 事件机制:socket.io使用事件机制来处理消息,使得代码更加简洁和易于维护。

总之,socket.io是一款功能强大、易于使用的实时通信库,可以帮助开发者轻松实现浏览器和服务器之间的实时通信。

Nest具体实现

首先需要安装依赖

npm install @nestjs/platform-socket.io

npm install @nestjs/websockets

新建一个文件用来接受广播消息和发送消息

events.gateway.ts

js 复制代码
import {
  ConnectedSocket,
  MessageBody,
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer,
} from '@nestjs/websockets';
import { Server,Socket } from 'socket.io';
// @WebSocketGateway是一个装饰器,用于创建WebSocket网关类。WebSocket网关类是用于处理 WebSocket连接和消息的核心组件之一。
// 它充当WebSocket服务端的中间人,负责处理客户端发起的连接请求,并定义处理不同类型消息的逻辑
@WebSocketGateway({ cors: { origin: '*' } })
export class EventGateway {
  constructor() {}
  @WebSocketServer()
  server: Server;

  @SubscribeMessage('newMessage')
  handleMessage(@MessageBody() body: any, @ConnectedSocket() client: Socket) {
    console.log(body);
    const msg: any = {};
    const { roomId, name,message } =body || {} 
    msg.text = message
    msg.name = name
    msg.roomId = roomId
    this.server.to(roomId).emit('newMessage', msg)
  }
  // 离开房间
  @SubscribeMessage('leave')
  handleLeave(@MessageBody() body: any, @ConnectedSocket() client: Socket) {
    const { roomId, name } =body || {} 
     // 先广播离开消息给房间内其他人
     this.server.to(roomId).emit('leave', `用户:${name}离开了房间 ${roomId}`);
     client.leave(roomId);
  }
  // 创建房间并加入房间
  @SubscribeMessage('join')
  handleJoin(@MessageBody() body: any, @ConnectedSocket() client: Socket) {
    const { roomId, name } =body || {} 
    client.join(roomId);
    // client只能给发送给发起请求的客户端
    // client.emit('join', `用户:${name}加入了房间 ${roomId}`);  
    // 广播消息给除自己以外的所有客户端
    // client.broadcast.emit('join', `用户:${name}加入了房间 ${roomId}`);
    // 使用服务器实例来广播消息给所有客户端
    this.server.to(roomId).emit('join', `用户:${name}加入了房间 ${roomId}`);
  }

  // 获取当前房间的人数
  @SubscribeMessage('getRoomUsers')
  handleGetRoomUsers(@MessageBody() body: any, @ConnectedSocket() client: Socket) {
    const room = this.server.sockets.adapter.rooms.get(body.roomId);
    if (room) {
      this.server.to(body.roomId).emit('getRoomUsers', room.size);
    } else {
      this.server.to(body.roomId).emit('getRoomUsers', 0);
    }
  }
}

在app.module.ts中

js 复制代码
import { EventGateway } from './events/events.gateway';

在providers中注入该服务

启动项目 yarn start

前端实现逻辑

安装依赖: npm install socket.io-client

先连接上socket.io

js 复制代码
import { io } from "socket.io-client";
const URL ='socket.io的地址'
const socket = io(URL);

socket.emit 发送消息

socket.on 监听消息

例如创建或加入房间 (nest代码中join事件,客户端这边连接上了socket.io,就可以通过对应事件实现双向通讯了)

js 复制代码
const createOrJoinRoom = () => {
  socket.emit("join", { roomId: props.state.roomId, name: props.state.name });
}

监听加入房间的事件,看看服务端回应广播的消息

js 复制代码
  socket.on('join', (e) => {
      console.log(e)
  });

其他的离开房间,发送消息等类似加入房间,具体可看源码

实现效果

前端样式比较简单具体实现效果如下:

体验地址

zymanage.yaoyaoqiekenao.com/

源码地址

github.com/DarknessZY/...

相关推荐
玩电脑的辣条哥3 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ew452183 小时前
ElementUI表格表头自定义添加checkbox,点击选中样式不生效
前端·javascript·elementui
suibian52353 小时前
AI时代:前端开发的职业发展路径拓宽
前端·人工智能
Moon.93 小时前
el-table的hasChildren不生效?子级没数据还显示箭头号?树形数据无法展开和收缩
前端·vue.js·html
垚垚 Securify 前沿站3 小时前
深入了解 AppScan 工具的使用:筑牢 Web 应用安全防线
运维·前端·网络·安全·web安全·系统安全
工业甲酰苯胺6 小时前
Vue3 基础概念与环境搭建
前端·javascript·vue.js
mosquito_lover17 小时前
怎么把pyqt界面做的像web一样漂亮
前端·python·pyqt
柴柴的小记9 小时前
前端vue引入特殊字体不生效
前端·javascript·vue.js
柠檬豆腐脑10 小时前
从前端到全栈:新闻管理系统及多个应用端展示
前端·全栈
bin915310 小时前
DeepSeek 助力 Vue 开发:打造丝滑的颜色选择器(Color Picker)
前端·javascript·vue.js·ecmascript·deepseek