简介

本文服务端以Nest官方模板,客户端以Vue3+Vite官方模板为例,简单介绍如何在Nest项目IO即时通讯中使用socket与Vue3的客户端。

初始化项目

服务器

# 安装 Nest 脚手架

$ npm i -g @nestjs/cli

创建一个嵌套后端项目

$ 嵌套新项目名称

启动项目

$纱线开始:开发

创建后:

# 服务器初始目录结构:

├── 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

启动项目

$纱线开发

创建后:

# 客户端初始目录结构:

├── 资产

├── 组件

├── app.vue

└── main.ts

安装需要的依赖

服务器

# 安装官方socket IO包

$纱线添加@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模块。

$ 巢 g res socketTest

模块自动生成后,项目目录如下:

├── 插座测试

├── dto

├── 实体

├── 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

打开套接字测试网关。 TS文件,如下:

进口{

WebSocket网关,

订阅消息,

消息正文,

} 来自“@nestjs/websockets”;

从“./socket-test.service”导入 { SocketTestService };

从“./dto/create-socket-test.dto”导入 { CreateSocketTestDto };

从“./dto/update-socket-test.dto”导入 { UpdateSocketTestDto };

/** @WebSocketGateway 装饰器可以传入一些配置选项,比如下面的例子:

* @WebSocketGateway(80, {

* 命名空间:“事件”,

* 传输:['websocket']

* cors: {

* 来源:'*'

* },

* ...

* })

**/

@WebSocketGateway({ cors: true })

出口类 SocketTestGateway {

构造函数(私有只读socketTestService:SocketTestService){}

@SubscribeMessage("createSocketTest")

create(@MessageBody() createSocketTestDto: CreateSocketTestDto) {

返回 this.socketTestService.create(createSocketTestDto);

}

@SubscribeMessage("findAllSocketTest")

findAll() {

返回 this.socketTestService.findAll();

}

@SubscribeMessage("findOneSocketTest")

findOne(@MessageBody() id: number) {

返回 this.socketTestService.findOne(id);

}

@SubscribeMessage("updateSocketTest")

update(@MessageBody() updateSocketTestDto: UpdateSocketTestDto) {

返回 this.socketTestService.update(

更新SocketTestDto.id,

更新SocketTestDto

);

}

@SubscribeMessage("removeSocketTest")

删除(@MessageBody() id:数字){

返回 this.socketTestService.remove(id);

}

}

客户端

在src目录下创建plugins文件夹,新建socket io。 TS插件,

├── 资产

├── 组件

├── 插件

├── Socket.io.ts

├── app.vue

└── main.ts

在套接字 io.在TS文件中写入如下内容,

// Socket.io.ts

从“socket.io 客户端”导入 { io };

导出默认 {

安装:(应用程序,{ 连接,选项 })u003d> {

常量套接字 u003d io(连接,选项);

app.config.globalProperties.$socket u003d 套接字;

app.provide("socket", socket);

},

};

然后在主 TS 文件中并将其挂载到应用程序上,

// main.ts

从“vue”导入 { createApp };

从“./App.vue”导入应用程序;

从“/@/plugins/Socket.io”导入 Socketio;

常量应用程序 u003d 创建应用程序(应用程序);

app.use(Socketio, {

connection: "/* 这里填写服务器地址,如http://localhost:3000 */",

选项:{

autoConnect: false, //关闭自动连接

// ... 其他选项

},

});

app.mount("#app");

然后在必要时使用套接字 Connect() 手动连接套接字。

实际应用

Nest 会在用@SubscribeMessage 修饰的方法中返回一条确认消息。我们可以直接返回 JSON 格式或字符串格式的数据。例如,我们添加一个测试事件:

// 服务器套接字测试网关。 ts

@SubscribeMessage('socketTest')

socketTest(@MessageBody() 数据:任意) {

Logger.log(data) // {test: '测试数据'}

返回{

msg1: '测试 1',

msg2: '测试 2',

}

}


// 客户端 HelloWorld vue

从'vue'导入{ ref,onMounted,注入};

从 'socket.io-client' 导入 { Socket };

const socket u003d inject('socket') as Socket;

socket.emit('socketTest', {test: '测试数据'}, (data) u003d> {

console.log(data) // {msg1: 'test 1', msg2: 'test 2'}

});

onMounted(() u003d> {

socket.connect(); //连接套接字服务器

});

有时可能需要在客户端发送消息后要求服务器将消息转发给客户端的另一个事件。我们可以在 return ing 的时候添加一个指定的事件事件,然后在客户端监听,比如:

// 服务器套接字测试网关。 ts

@SubscribeMessage('socketTest')

socketTest(@MessageBody() 数据:任意) {

返回{

事件:'socketTest2',

数据

}

}


// 客户端 HelloWorld vue

从'vue'导入{ ref,onMounted,注入};

从 'socket.io-client' 导入 { Socket };

const socket u003d inject('socket') as Socket;

socket.emit('socketTest',{ msg1: '测试 1', msg2: '测试 2' })

socket.on('socketTest2', (数据) u003d> {

console.log(data) // {msg1: 'test 1', msg2: 'test 2'}

});

onMounted(() u003d> {

socket.connect(); //连接套接字服务器

});

上面虽然解决了客户端和服务端的通信问题,但其实我们的项目可能没有这么简单,可能是socket对于不同ID的多个客户端,我们需要使用@nestjs导出的@ConnectedSocket()装饰器/websockets 包获取socket 对于IO的实例,使用政府提供的一些API来定义事件。以广播事件为例:

// 服务器套接字测试网关。 ts

@SubscribeMessage('socketTest')

socketTest(@MessageBody() 数据:任意,@ConnectedSocket() 客户端:Socket) {

client.broadcast.emit('socket Test2', data);

}


// Client-1 HelloWorld vue

从'vue'导入{ ref,onMounted,注入};

从 'socket.io-client' 导入 { Socket };

const socket u003d inject('socket') as Socket;

socket.emit('socketTest',{ msg1: '测试 1', msg2: '测试 2' })

socket.on('socketTest2', (数据) u003d> {

console.log(data) // {msg1: 'test 1', msg2: 'test 2'}

});

onMounted(() u003d> {

socket.connect(); //连接套接字服务器

});


// 客户端 - 2布局vue

从'vue'导入{ ref,onMounted,注入};

从 'socket.io-client' 导入 { Socket };

const socket u003d inject('socket') as Socket;

socket.on('socketTest2', (数据) u003d> {

console.log(data) // {msg1: 'test 1', msg2: 'test 2'}

});

onMounted(() u003d> {

socket.connect(); //连接套接字服务器

});

本文首发于https://www.cnblogs.com/China-Dream/p/15827701.html

Logo

前往低代码交流专区

更多推荐