的使用介绍本文以服务端Nest官方模板和客户端Vue3+Vite官方模板为例,简单介绍如何使用socket.io和Vue3客户端在Nest项目中进行实时通信。初始化项目服务器#安装Nest脚手架$npmi-g@nestjs/cli#创建nest后端项目$nestnewproject-name#启动项目$yarnstart:dev创建后:#服务器初始目录结构:src├──app.controller.spec.ts├──app.controller.ts├──app.module.ts├──app.service.ts└──main.tsclient#安装vite脚手架$npminitvite@latest#创建一个vue前端项目$npminitvite@latestmy-vue-app----templatevue#创建后启动项目$yarndev:#客户端初始目录结构:src├──assets├──components├──App.vue└──main.ts安装需要依赖服务器#安装官方提供的socket.io包$yarnadd@nestjs/websockets@nestjs/platform-socket.ioclient#安装官方提供的socket。iopackage$yarnaddsocket.io-client注意:Nestv7及以下版本依赖socket.iov2,Nestv8依赖socket.iov4,请检查版本兼容性。服务端和客户端的socket.io依赖包版本必须一致,否则可能会连接不上或者报跨域错误。配置websocketserver#使用官方的cli工具在项目中生成一个websocket模块。$nestgressocketTest自动生成模块后,工程目录如下所示: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,来自“@nestjs/websockets”;从“./socket-test.service”导入{SocketTestService};从“./dto/create-socket-test.dto”导入{CreateSocketTestDto};从“导入{UpdateSocketTestDto}”。/dto/update-socket-test.dto";/**@WebSocketGateway装饰器可以传入一些配置选项,例如下面的例子:*@WebSocketGateway(80,{*namespace:'events',*transports:['websocket']*cors:{*origin:'*'*},*...*})**/@WebSocketGateway({cors:true})exportclassSocketTestGateway{constructor(privatereadonlyssocketTestService:SocketTestService){}@SubscribeMessage("createSocketTest")创建(@MessageBody()createSocketTestDto:CreateSocketTestDto){returnthis.socketTestService.create(createSocketTestDto);}@SubscribeMessage("findAllSocketTest")findAll(){.。找到所有();}@SubscribeMessage("findOneSocketTest")findOne(@MessageBody()id:number){returnthis.socketTestService.findOne(id);}@SubscribeMessage("updateSocketTest")更新(@MessageBody()updateSocketTestDto:UpdateSocketTestDto){returnthis.socketTestService.update(updateSocketTestDto.id,updateSocketTestDto);}@SubscribeMessage("removeSocketTest")remove(@MessageBody()id:number){returnthis.socketTestService.remove(id);}}client在src目录下新建一个plugins文件夹,在里面新建一个Socket.io.ts插件,src├──assets├──components├──plugins├──Socket.io.ts├──App.vue└──main.ts在Socket.io.ts文件中写入如下内容,//Socket.io.tsimport{io}from"socket.io-client";exportdefault{install:(app,{connection,options})=>{constsocket=io(connection,options);app.config.globalProperties.$socket=socket;应用程序.provide("套接字",套接字);},};然后在main.ts文件中导入并挂载到app上,//main.tsimport{createApp}from"vue";importAppfrom"./App.vue";importSocketiofrom"/@/plugins/Socket.io";constapp=createApp(App);app.use(Socketio,{connection:"/*这里填写服务器地址,比如http://localhost:3000*/",options:{autoConnect:false,//关闭自动连接//...其他选项},});app.mount("#app");然后使用socket.connect()手动连接套接字实际使用Nest在@SubscribeMessage修饰的方法中,会返回一条确认信息。我们可以直接返回JSON格式或者字符串格式的数据。例如,我们添加一个测试事件://serversocket-test.gateway.ts@SubscribeMessage('socketTest')socketTest(@MessageBody()data:any){Logger.log(data)//{test:'testdata'}return{msg1:'test1',msg2:'test2',}}---------------------------------//ClientHelloWorld.vueimport{ref,onMounted,inject}from'vue';import{Socket}from'socket.io-client';constsocket=inject('socket')asSocket;socket.emit('socketTest',{test:'testdata'},(data)=>{console.log(data)//{msg1:'Test1',msg2:'Test2'}});onMounted(()=>{socket.connect();//连接套接字服务器});是的有时可能需要服务端在客户端发送消息后,将消息转发给客户端的另一个事件。我们可以在返回的时候添加一个指定的事件事件,然后在客户端监听,例如://serversocket-test.gateway.ts@SubscribeMessage('socketTest')socketTest(@MessageBody()data:any){return{event:'socketTest2',data}}------------------------------//ClientHelloWorld.vueimport{ref,onMounted,inject}from'vue';import{Socket}from'socket.io-client';constsocket=inject('socket')asSocket;socket.emit('socketTest',{msg1:'Test1',msg2:'Test2'})socket.on('socketTest2',(data)=>{console.log(data)//{msg1:'Test1',msg2:'Test2'}});onMounted(()=>{socket.connect();//连接到套接字服务器});上面虽然解决了客户端和服务端的通信问题,但实际上我们的项目可能并没有这么简单,可能会有多个不同socket.ids的客户端,在这种情况下,接下来我们需要使用@ConnectedSocket()@nestjs/websockets包导出的装饰器,获取socket.io实例,使用官方的一些API定义事件,以广播事件为例://serversocket-test.gateway.ts@SubscribeMessage('socketTest')socketTest(@MessageBody()data:any,@ConnectedSocket()clinet:Socket){clinet.broadcast.emit('socketTest2',data);}----------------------------------//client-1HelloWorld.vueimport{ref,onMounted,inject}from'vue';import{Socket}from'socket.io-client';constsocket=inject('socket')asSocket;socket.emit('socketTest',{msg1:'Test1',msg2:'Test2'})socket.on('socketTest2',(data)=>{console.log(data)//{msg1:'Test1',msg2:'Test2'}});onMounted(()=>{socket.connect();//连接套接字服务器});---------------------------------//client-2Layout.vueimport{ref,onMounted,inject}from'vue';import{Socket}from'socket.io-client';constsocket=inject('socket')作为套接字;socket.on('socketTest2',(data)=>{console.log(data)//{msg1:'Test1',msg2:'Test2'}});onMounted(()=>{socket.connect();//连接套接字服务器});本文首发于https://www.cnblogs.com/China-Dream/p/15827701.html
