如何在Nestjs和Vue3中使用socket.io示例详解
作者:余以为
这篇文章主要为大家介绍了如何在Nestjs和Vue3中使用socket.io示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
简介
本文服务端以 Nest 官方模板,客户端以 Vue3 + Vite 官方模板为例,简单介绍如何在 Nest 项目中使用 socket.io 与 Vue3 的客户端进行即时通讯。
初始化项目
服务端
# 安装Nest脚手架 $ npm i -g @nestjs/cli # 创建一个nest后端项目 $ nest new project-name # 启动项目 $ yarn start:dev
创建完毕后:
# 服务端初始目录结构: src ├── app.controller.spec.ts ├── app.controller.ts ├── app.module.ts ├── app.service.ts └── main.ts
客户端
# 安装vite脚手架 $ npm init vite@latest # 创建一个vue前端端项目 $ npm init vite@latest my-vue-app -- --template vue # 启动项目 $ yarn dev
创建完毕后:
# 客户端初始目录结构: src ├── assets ├── components ├── App.vue └── main.ts
安装所需依赖
服务端
# 安装官方提供的socket.io包 $ yarn add @nestjs/websockets @nestjs/platform-socket.io
客户端
# 安装官方提供的socket.io包 $ yarn add socket.io-client
注意:
Nest v7
及以下版本依赖于socket.io v2
,Nest v8
依赖于socket.io v4
,请注意查看版本的兼容性。- 服务端和客户端
socket.io
依赖包版本必须保持一致,否则将有可能无法连接或者报跨域等错误。
配置 websocket
服务端
# 使用官方cli工具在项目中生成一个websocket模块。 $ nest g res socketTest
自动生成模块之后,项目目录是这样的:
src ├── socket-test ├── dto ├── entities ├── socket-test.gateway.spec.ts ├── socket-test.gateway.ts ├── socket-test.module.ts ├── socket-test.service.spec.ts ├── socket-test.service.ts ├── app.controller.spec.ts ├── app.controller.ts ├── app.module.ts ├── app.service.ts └── main.ts
打开socket-test.gateway.ts
文件,内容如下:
import { WebSocketGateway, SubscribeMessage, MessageBody, } from "@nestjs/websockets"; import { SocketTestService } from "./socket-test.service"; import { CreateSocketTestDto } from "./dto/create-socket-test.dto"; import { UpdateSocketTestDto } from "./dto/update-socket-test.dto"; /** @WebSocketGateway装饰器可传入一些配置选项,如下面的示例: * @WebSocketGateway(80, { * namespace: 'events', * transports: ['websocket'] * cors: { * origin: '*' * }, * ... * }) **/ @WebSocketGateway({ cors: true }) export class SocketTestGateway { constructor(private readonly socketTestService: SocketTestService) {} @SubscribeMessage("createSocketTest") create(@MessageBody() createSocketTestDto: CreateSocketTestDto) { return this.socketTestService.create(createSocketTestDto); } @SubscribeMessage("findAllSocketTest") findAll() { return this.socketTestService.findAll(); } @SubscribeMessage("findOneSocketTest") findOne(@MessageBody() id: number) { return this.socketTestService.findOne(id); } @SubscribeMessage("updateSocketTest") update(@MessageBody() updateSocketTestDto: UpdateSocketTestDto) { return this.socketTestService.update( updateSocketTestDto.id, updateSocketTestDto ); } @SubscribeMessage("removeSocketTest") remove(@MessageBody() id: number) { return this.socketTestService.remove(id); } }
客户端
在 src 目录下创建 plugins 文件夹,于其中新建一个 Socket.io.ts 插件,
src ├── assets ├── components ├── plugins ├── Socket.io.ts ├── App.vue └── main.ts
在 Socket.io.ts 文件中写入下面的内容,
// Socket.io.ts import { io } from "socket.io-client"; export default { install: (app, { connection, options }) => { const socket = io(connection, options); app.config.globalProperties.$socket = socket; app.provide("socket", socket); }, };
然后在 main.ts 文件中引入进来,挂载到 app 上,
// main.ts import { createApp } from "vue"; import App from "./App.vue"; import Socketio from "/@/plugins/Socket.io"; const app = createApp(App); app.use(Socketio, { connection: "/* 这里填写服务端地址,如 http://localhost:3000 */", options: { autoConnect: false, //关闭自动连接 // ...其它选项 }, }); app.mount("#app");
然后在需要的时候使用socket.connect()
手动连接 socket。
实际运用
Nest 在使用@SubscribeMessage
装饰的方法中,会return
一个确认信息,我们可以直接返回 JSON 格式或是字符串格式数据,比如我们添加一个测试事件:
// 服务端 socket-test.gateway.ts @SubscribeMessage('socketTest') socketTest(@MessageBody() data: any) { Logger.log(data) // {test: '测试数据'} return { msg1: '测试1', msg2: '测试2', } } ---------------------------------- // 客户端 HelloWorld.vue import { ref, onMounted, inject } from 'vue'; import { Socket } from 'socket.io-client'; const socket = inject('socket') as Socket; socket.emit('socketTest', {test: '测试数据'}, (data) => { console.log(data) // { msg1: '测试1', msg2: '测试2' } }); onMounted(() => { socket.connect(); //连接socket服务器 });
有时候可能需要在客户端发送消息后,让服务端把消息再转发给客户端的另一个事件中,我们可以在 return 的时候增加一个指定事件 event,然后在客户端进行监听,比如:
// 服务端 socket-test.gateway.ts @SubscribeMessage('socketTest') socketTest(@MessageBody() data: any) { return { event: 'socketTest2', data } } ---------------------------------- // 客户端 HelloWorld.vue import { ref, onMounted, inject } from 'vue'; import { Socket } from 'socket.io-client'; const socket = inject('socket') as Socket; socket.emit('socketTest',{ msg1: '测试1', msg2: '测试2' }) socket.on('socketTest2', (data) => { console.log(data) // { msg1: '测试1', msg2: '测试2' } }); onMounted(() => { socket.connect(); //连接socket服务器 });
上面虽然解决了客户端与服务端相互通信的问题,但实际上我们的项目可能不会这么简单,有可能是socket.id
不同的多个客户端,这种情况下我们就需要使用@nestjs/websockets
包导出的@ConnectedSocket()
装饰器,获取到 socket.io 的实例,使用官方提供的一些 Api 来定义事件,以广播事件为例:
// 服务端 socket-test.gateway.ts @SubscribeMessage('socketTest') socketTest(@MessageBody() data: any, @ConnectedSocket() clinet: Socket) { clinet.broadcast.emit('socketTest2', data); } ---------------------------------- // 客户端-1 HelloWorld.vue import { ref, onMounted, inject } from 'vue'; import { Socket } from 'socket.io-client'; const socket = inject('socket') as Socket; socket.emit('socketTest',{ msg1: '测试1', msg2: '测试2' }) socket.on('socketTest2', (data) => { console.log(data) // { msg1: '测试1', msg2: '测试2' } }); onMounted(() => { socket.connect(); //连接socket服务器 }); ---------------------------------- // 客户端-2 Layout.vue import { ref, onMounted, inject } from 'vue'; import { Socket } from 'socket.io-client'; const socket = inject('socket') as Socket; socket.on('socketTest2', (data) => { console.log(data) // { msg1: '测试1', msg2: '测试2' } }); onMounted(() => { socket.connect(); //连接socket服务器 });
以上就是如何在Nestjs和Vue3中使用socket.io示例详解的详细内容,更多关于Nestjs Vue3使用socket.io的资料请关注脚本之家其它相关文章!