如何在Nestjs和Vue3中使用socket.io示例詳解
簡介
本文服務(wù)端以 Nest 官方模板,客戶端以 Vue3 + Vite 官方模板為例,簡單介紹如何在 Nest 項目中使用 socket.io 與 Vue3 的客戶端進(jìn)行即時通訊。
初始化項目
服務(wù)端
# 安裝Nest腳手架 $ npm i -g @nestjs/cli # 創(chuàng)建一個nest后端項目 $ nest new project-name # 啟動項目 $ yarn start:dev
創(chuàng)建完畢后:
# 服務(wù)端初始目錄結(jié)構(gòu): src ├── app.controller.spec.ts ├── app.controller.ts ├── app.module.ts ├── app.service.ts └── main.ts
客戶端
# 安裝vite腳手架 $ npm init vite@latest # 創(chuàng)建一個vue前端端項目 $ npm init vite@latest my-vue-app -- --template vue # 啟動項目 $ yarn dev
創(chuàng)建完畢后:
# 客戶端初始目錄結(jié)構(gòu): src ├── assets ├── components ├── App.vue └── main.ts
安裝所需依賴
服務(wù)端
# 安裝官方提供的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
,請注意查看版本的兼容性。- 服務(wù)端和客戶端
socket.io
依賴包版本必須保持一致,否則將有可能無法連接或者報跨域等錯誤。
配置 websocket
服務(wù)端
# 使用官方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
文件,內(nèi)容如下:
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 目錄下創(chuàng)建 plugins 文件夾,于其中新建一個 Socket.io.ts 插件,
src ├── assets ├── components ├── plugins ├── Socket.io.ts ├── App.vue └── main.ts
在 Socket.io.ts 文件中寫入下面的內(nèi)容,
// 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 文件中引入進(jìn)來,掛載到 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: "/* 這里填寫服務(wù)端地址,如 http://localhost:3000 */", options: { autoConnect: false, //關(guān)閉自動連接 // ...其它選項 }, }); app.mount("#app");
然后在需要的時候使用socket.connect()
手動連接 socket。
實際運用
Nest 在使用@SubscribeMessage
裝飾的方法中,會return
一個確認(rèn)信息,我們可以直接返回 JSON 格式或是字符串格式數(shù)據(jù),比如我們添加一個測試事件:
// 服務(wù)端 socket-test.gateway.ts @SubscribeMessage('socketTest') socketTest(@MessageBody() data: any) { Logger.log(data) // {test: '測試數(shù)據(jù)'} 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: '測試數(shù)據(jù)'}, (data) => { console.log(data) // { msg1: '測試1', msg2: '測試2' } }); onMounted(() => { socket.connect(); //連接socket服務(wù)器 });
有時候可能需要在客戶端發(fā)送消息后,讓服務(wù)端把消息再轉(zhuǎn)發(fā)給客戶端的另一個事件中,我們可以在 return 的時候增加一個指定事件 event,然后在客戶端進(jìn)行監(jiān)聽,比如:
// 服務(wù)端 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服務(wù)器 });
上面雖然解決了客戶端與服務(wù)端相互通信的問題,但實際上我們的項目可能不會這么簡單,有可能是socket.id
不同的多個客戶端,這種情況下我們就需要使用@nestjs/websockets
包導(dǎo)出的@ConnectedSocket()
裝飾器,獲取到 socket.io 的實例,使用官方提供的一些 Api 來定義事件,以廣播事件為例:
// 服務(wù)端 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服務(wù)器 }); ---------------------------------- // 客戶端-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服務(wù)器 });
以上就是如何在Nestjs和Vue3中使用socket.io示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Nestjs Vue3使用socket.io的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
nodejs服務(wù)搭建教程 nodejs訪問本地站點文件
這篇文章主要為大家詳細(xì)介紹了nodejs服務(wù)搭建教程,訪問本地站點文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04nodejs socket服務(wù)端和客戶端簡單通信功能
這篇文章主要為大家詳細(xì)介紹了nodejs socket服務(wù)端和客戶端簡單通信功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09Node環(huán)境中JS代碼缺少window對象的原因和解決方案
你可能會在某些情況下需要在Node環(huán)境下運行JavaScript代碼,但你也可能會遇到一個常見的問題:缺少window環(huán)境,在本文中,我們將深入探討這個問題的原因,并提供解決方案,需要的朋友可以參考下2023-08-08node.js使用免費的阿里云ip查詢獲取ip所在地【推薦】
這篇文章主要介紹了node.js使用免費的阿里云ip查詢獲取ip所在地的相關(guān)知識,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下2018-09-09