0


vue3项目使用WebSocket 传输 Protobuf 格式的数据

vue3项目使用WebSocket 传输 Protobuf 格式的数据


前言

前端和后端数据传输常用数据格式:

JSON(JavaScript Object Notation):与 HTTP 协议和 REST API 配合使用时,JSON 数据是最常用的数据格式之一。对于 WebSocket,JSON 数据同样适用。客户端可以将消息转换为 JSON 对象,并将其发送到服务器进行处理,在服务器上生成响应并返回给客户端。

Binary Data:WebSocket 还支持二进制数据传输。此方法特别适用于需要在网络上传输大量数据的应用程序。使用二进制数据格式,您可以将数据压缩为更小的包,以提高传输速度并降低带宽消耗。

Protocol Buffers:Protocol Buffers 是一种 Google 开发的高效数据结构序列化格式。与 JSON 和 XML 不同,Protocol Buffers 将数据编码为二进制格式,可快速解析和传输。此方法特别适用于需要在网络上传输大量数据的应用程序。

但是在日常开发当中使用的最多的还是JSON格式

下面我简单介绍一下前后端使用protobuf传输数据的案例


一、基础库安装

pnpm add ws
pnpm add protobufjs
pnpm add protobufjs-cli -D

二、具体代码实现

本文完整示例代码

1.服务端编写

message.proto文件定义

syntax = "proto3";

message Message {
  string text = 1;
}

代码如下(示例):

const WebSocket =require('ws');const protobuf =require('protobufjs');const path =require('path');// 加载 .proto 文件const root =newprotobuf.Root();
root.loadSync(path.join(__dirname,'./message.proto'));// 获取 Message 类型const Message = root.lookupType('Message');// 创建 WebSocket 服务器const server =newWebSocket.Server({ port:8080});

server.on('connection',(socket:any)=>{console.log('Client connected');// 接收客户端发送的消息
    socket.on('message',(data: Buffer)=>{const message = Message.decode(newUint8Array(data));console.log('Received message:', message);// 发送响应消息// const response = { text: 'Hello, client!'};// const buffer = Message.encode(Message.fromObject(response)).finish();// socket.send(buffer);const response = Message.create({ text:`服务端已收到数据: ${message.text}`});// 序列化消息对象,并将其发送给服务器const buffer = Message.encode(response).finish();
        socket.send(buffer);});// 监听连接断开事件
    socket.on('close',()=>{console.log('Client disconnected');});});const http =require('http');const fs =require('fs');// 创建 HTTP 服务器,监听客户端请求const httpserver = http.createServer(async(req:any, res:any)=>{console.log(`Receive request: ${req.method}${req.url}`);try{// 如果请求的是 .proto 文件,则读取文件内容并返回给客户端if(req.url.endsWith('.proto')){const content =await fs.promises.readFile(`${path.join(__dirname,'./message.proto')}`,'utf8');
            res.setHeader('content-type','text/plain');
            res.end(content);return;}// 如果请求的不是 .proto 文件,则返回 404 Not Found 错误
        res.statusCode =404;
        res.end();}catch(err){console.error(err);
        res.statusCode =500;
        res.end();}});// 启动 HTTP 服务器
httpserver.listen(3001,()=>{console.log('HTTP server started!');});

2.客户端代码实现

方法1

代码如下(示例):

<template><div style="width: 100%; height: 200px; background: darkgrey"><div>{{ messageRef }}</div><button @click="sendMsg"> 发送 </button></div></template><script setup lang="ts">import{ ref }from'vue';import protobuf from'protobufjs';// 定义要加载的 .proto 文件 URLconst protoUrl ='/path/to/your/message.proto';// 定义响应消息的状态const messageRef =ref('');const response =awaitfetch(protoUrl);const content =await response.text();// 解析 .proto 文件中的消息结构const root =await protobuf.parse(content).root;const MyMessage = root.lookupType('Message');// 创建 WebSocket 连接const ws =newWebSocket('ws://localhost:8080/');// 监听 WebSocket 连接成功事件
ws.addEventListener('open',()=>{console.log('WebSocket connected!');// 序列化消息对象,并将其发送给服务器const response = MyMessage.create({ text:'客户端1连接了'});// 序列化消息对象,并将其发送给服务器const buffer = MyMessage.encode(response).finish();
  ws.send(buffer);});// 监听 WebSocket 收到服务器发送过来的消息事件
ws.addEventListener('message',async(event)=>{// 解析二进制数据为 Protobuf 消息const blob: Blob = event.data;// Uint8Array 接收的是arrayBuffer对象这里一定要注意如果是Blob格式的数据一定要先转为arrayBufferconst buffer =await blob.arrayBuffer();const data =newUint8Array(buffer);const message = MyMessage.decode(data);console.log(`Receive message from server: ${JSON.stringify(message)}`);// 更新视图显示收到的消息内容
  messageRef.value = message.text;});// 监听 WebSocket 出错事件
ws.addEventListener('error',(event)=>{console.error(event);});// 监听 WebSocket 关闭事件
ws.addEventListener('close',(event)=>{console.warn(event);});constsendMsg=()=>{const message = MyMessage.create({ text:'我是客户端1'});// 序列化消息对象,并将其发送给服务器const buffer = MyMessage.encode(message).finish();
  ws.send(buffer);};</script>

方法2

方法2不同之处在与使用

protobufjs-cli

工具将

message.proto

文件编译出js文件 还能编译出ts声明文件,具有类型提示对TS项目更加友好

编译方法

pbjs -t static-module -w es6 -o ../web/src/components/compiled.js message.proto
pbts -o ../web/src/components/compiled.d.ts ../web/src/components/compiled.js

该方法脚本已经写在了本文完整示例代码的

/packages/server/package.json

文件中
在这里插入图片描述

代码实现

<template><div style="width: 100%; height: 200px; background: #d3d3d3"><code>{{ messageRef }}</code><button @click="sendMsg"> 发送 </button></div></template><script setup lang="ts">import{ ref }from'vue';import{ Message }from'./compiled';// 使用protobufjs-cli编译出来的包const messageRef =ref('');// 创建 WebSocket 连接const ws =newWebSocket('ws://localhost:8080/');// 监听 WebSocket 连接成功事件
ws.addEventListener('open',()=>{console.log('WebSocket connected1!');// 序列化消息对象,并将其发送给服务器const buffer = Message.encode({ text:'客户端2连接了'}).finish();
  ws.send(buffer);});// 监听 WebSocket 收到服务器发送过来的消息事件
ws.addEventListener('message',async(event)=>{// 解析二进制数据为 Protobuf 消息const blob: Blob = event.data;// Uint8Array 接收的是arrayBuffer对象这里一定要注意如果是Blob格式的数据一定要先转为arrayBufferconst buffer =await blob.arrayBuffer();const data =newUint8Array(buffer);const message = Message.decode(data);console.log(`Receive message from server: ${JSON.stringify(message)}`);// 更新视图显示收到的消息内容
  messageRef.value = message.text;});// 监听 WebSocket 出错事件
ws.addEventListener('error',(event)=>{console.error(event);});// 监听 WebSocket 关闭事件
ws.addEventListener('close',(event)=>{console.warn(event);});constsendMsg=()=>{// 序列化消息对象,并将其发送给服务器const buffer = Message.encode({ text:'我是客户端2'}).finish();
  ws.send(buffer);};</script>

总结

以上就是vue3项目中传输protobuf数据的基本使用方法,仅供参考,如果有问题请留言评论。


本文转载自: https://blog.csdn.net/qq_43399210/article/details/129657443
版权归原作者 JokerLee... 所有, 如有侵权,请联系我们删除。

“vue3项目使用WebSocket 传输 Protobuf 格式的数据”的评论:

还没有评论