前端项目对接protobufjs的时候,踩坑总结

发布时间:2024年01月23日

Protobuf(Protocol Buffers)是一种用于序列化结构化数据的语言无关、平台无关、可扩展的机制。在JS/TS项目中,使用WebSocket与Protobuf可以实现高效的通信和数据传输。protobufjs官方仓库:https://github.com/protobufjs/protobuf.js

安装protobuf.js依赖

安装protobuf.js依赖的时候,如果你使用的cnpm源或者不是npm官方源的话,可能会报错说找不到这个依赖,需要更换为官方的npm源然后安装:https://xiaoshen.blog.csdn.net/article/details/135767569

定义proto文件

我在本地定义了一个简单的proto文件:person.proto

syntax = "proto3";
package example;

message person {
    int32 id = 1;
    string name = 2;
}

message person_list {
    repeated person Per = 1;
}

编译proto文件报错问题

编译的时候,需要使用es6模式的,不能使用commonjs,不然会报:

pnpm pbjs -t static-module -w es6 -o src/proto/person.js src/proto/person.proto

错误的编译命令:

pnpm pbjs -t static-module -w commonjs -o  src/proto/person.js src/proto/person.proto

Uncaught SyntaxError: The requested module does not provide an export named

WebSocket发送Protobuf消息

将WebSocket和Protobuf结合起来使用,可以实现高效的通信和数据传输。在发送消息时,可以先将消息对象序列化成二进制数据,然后再通过WebSocket发送:

binaryType说明:WebSocket.binaryType - Web API 接口参考 | MDN

const ws = new WebSocket('ws://192.168.1.171:8989/echo');
// 必须加上,不然解析出来的数据为空
ws.binaryType = "arraybuffer"

在接收消息时,可以先将接收到的二进制数据反序列化成消息对象,然后再进行处理:

不然会报错:protobufjs_minimal.js?v=b54c0ab3:1044 Uncaught Error: illegal buffer

ws.onmessage = function (event) {
  console.log('Received: ' + event.data);
  // 必须使用Uint8Array解析数据,不然解析不出来
  const res = protoRoot.example.all_person.decode(new Uint8Array(event.data));
  console.log("解码后的内容:", res);
  count.value = res;

};

通过结合WebSocket和Protobuf,可以实现更高效、更可靠的数据传输,提升JS/TS项目的性能和开发效率。?

我本地的写的完整代码:

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import protoRoot from "@/proto/person.js"

const count: any = ref()
const ws = new WebSocket('ws://192.168.1.171:8989/echo');
// 必须加上,不然解析出来的数据为空
ws.binaryType = "arraybuffer"
// 接收到消息时的处理逻辑
ws.onmessage = (event) => {
  count.value = event.data;
}
// 发送消息
ws.onopen = () => {
  ws.send('Hello, server!');
}

ws.onmessage = function (event) {
  console.log('Received: ' + event.data);
  // 必须使用Uint8Array解析数据,不然解析不出来
  const res = protoRoot.example.person_list.decode(new Uint8Array(event.data));
  console.log("解码后的内容:", res);
  count.value = res;
};

ws.onclose = function (event) {
  console.log('WebSocket connection closed', event);
};

// 页面初始化
onMounted(() => {
  console.log("组件加载:", protoRoot);
})

</script>

<template>
  <div>
    <div>wbsocket消息:</div>
    <div>{{ count }}</div>
  </div>
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}

.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}

.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

文章来源:https://blog.csdn.net/weixin_44786530/article/details/135780730
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。