Skip to content

Nest 开发 websocket

安装

bash

pnpm i --save @nestjs/websockets @nestjs/platform-socket.io

创建一个模块

bash
nest g resource websocket
  • 这里特别注意选择的时候一定要选择 websocket不能选择 RestFulApi

代码生成结构

bash
src
└── websocket
    ├── websocket.gateway.ts
    ├── websocket.module.ts
    └── websocket.service.ts

编写代码

websocket.gateway.ts(最重点)

  • 它相当于模块路由
typescript
import {
  WebSocketGateway,
  SubscribeMessage,
  MessageBody,
  ConnectedSocket,
  WebSocketServer,
  OnGatewayInit,
  OnGatewayConnection,
  OnGatewayDisconnect,
} from "@nestjs/websockets";
import { WebsocketService } from "./websocket.service";
import { CreateWebsocketDto } from "./dto/create-websocket.dto";
import { UpdateWebsocketDto } from "./dto/update-websocket.dto";
import { Server } from "socket.io";

// 增加跨域
// 声明 这是处理一个websocket的累,端口和监听端口一样
@WebSocketGateway({ cors: { origin: "*" } })
export class WebsocketGateway
  implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
  constructor(private readonly websocketService: WebsocketService) {}

  // 引入第三方(一般不用)
  @WebSocketServer()
  server: Server;

  // 生命周期函数
  handleDisconnect(client: Server) {
    console.log("000");
    // console.log(client);
  }

  handleConnection(client: Server, ...args: any[]) {
    console.log("111");
    // console.log(client);
  }

  afterInit(server: Server) {
    console.log("2222");
    // console.log(server);
  }

  // @SubscribeMessage 就是监听发过来消息
  // @MessageBody 取出传递过来的消息
  @SubscribeMessage("createWebsocket")
  create(@MessageBody() createWebsocketDto: CreateWebsocketDto) {
    return this.websocketService.create(createWebsocketDto);
  }

  @SubscribeMessage("findAllWebsocket")
  findAll() {
    return this.websocketService.findAll();
  }

  @SubscribeMessage("findOneWebsocket")
  findOne(@MessageBody() id: number) {
    return this.websocketService.findOne(id);
  }

  @SubscribeMessage("updateWebsocket")
  update(@MessageBody() updateWebsocketDto: UpdateWebsocketDto) {
    return this.websocketService.update(
      updateWebsocketDto.id,
      updateWebsocketDto
    );
  }

  @SubscribeMessage("removeWebsocket")
  remove(@MessageBody() id: number) {
    return this.websocketService.remove(id);
  }

  @SubscribeMessage("findAllWebsocket")
  sendtest1() {
    return {
      event: "test1",
      data: this.websocketService.sendtest1(),
    };
  }

  @SubscribeMessage("createThird")
  createThird(@MessageBody() id: number) {
    this.server.emit("test1", 6666);
    return this.websocketService.sendtest1();
  }
}

备注

  • @WebSocketGateway({ cors: { origin: "*" } }) 必须加上 否则不会跨域

  • @SubscribeMessage就是监听前端发过来的事件

  • @MessageBody就是取出前端传递过来的数据

  • 如果不想原路返回.可以自己定义一个事件,前端使用on监听即可

websocket.module.ts

typescript
import { Module } from "@nestjs/common";
import { WebsocketService } from "./websocket.service";
import { WebsocketGateway } from "./websocket.gateway";

@Module({
  providers: [WebsocketGateway, WebsocketService],
})
export class WebsocketModule {}

websocket.service.ts

typescript
import { Injectable } from "@nestjs/common";
import { CreateWebsocketDto } from "./dto/create-websocket.dto";
import { UpdateWebsocketDto } from "./dto/update-websocket.dto";
import { Observable } from "rxjs";

@Injectable()
export class WebsocketService {
  create(createWebsocketDto: CreateWebsocketDto) {
    return "This action adds a new websocket";
  }

  // 增加事件流
  findAll() {
    return new Observable((observer) => {
      observer.next({ event: "test1", data: { msg: "aaa" } });
      setTimeout(() => {
        observer.next({ event: "test1", data: { msg: "bbb" } });
      }, 2000);
      setTimeout(() => {
        observer.next({ event: "test1", data: { msg: "ccc" } });
      }, 5000);
    });
  }

  findOne(id: number) {
    return `This action returns a #${id} websocket`;
  }

  update(id: number, updateWebsocketDto: UpdateWebsocketDto) {
    return `This action updates a #${id} websocket`;
  }

  remove(id: number) {
    return `This action removes a #${id} websocket`;
  }

  sendtest1() {
    return `测试test1方法`;
  }
}

前端页面

html
<html>
  <head>
    <script
      src="https://cdn.socket.io/4.3.2/socket.io.min.js"
      integrity="sha384-KAZ4DtjNhLChOB/hxXuKqhMLYvx3b5MlT55xPEiNmREKRzeEm+RVPlTnAn0ajQNs"
      crossorigin="anonymous"
    ></script>
    <script>
      const socket = io("http://localhost:5000");
      socket.on("connect", function () {
        console.log("Connected");

        socket.emit("findAllWebsocket", (response) =>
          console.log("findAllWebsocket", response)
        );

        socket.emit("findOneWebsocket", 1, (response) =>
          console.log("findOneWebsocket", response)
        );

        socket.emit("createWebsocket", { name: "test1" }, (response) =>
          console.log("createWebsocket", response)
        );

        socket.emit("updateWebsocket", { id: 2, name: "dong" }, (response) =>
          console.log("updateWebsocket", response)
        );

        socket.emit("removeWebsocket", 2, (response) =>
          console.log("removeWebsocket", response)
        );

        socket.emit("createThird", { id: 2, name: "dong" }, (response) =>
          console.log("createThird", response)
        );
        // 监听返回的事件里面是不是test1
        socket.on("test1", (response) => console.log("test1", response));
      });
      socket.on("disconnect", function () {
        console.log("Disconnected");
      });
    </script>
  </head>

  <body></body>
</html>