资讯专栏INFORMATION COLUMN

基于http协议使用protobuf进行前后端交互

hersion / 1778人阅读

摘要:呵呵呵打印出来的是二进制流需要进行化然后给前端。不然的话浏览器会自动解析成文字的前端需要进行接受二进制流先引入文件以及插件前端用请求的路由,在回调函数里的为后端的返回值。

protobuf介绍 由于网上关于protobuf的交互的资料比较零散,所以自己整理了一下关于protobuf前后端交互的资料,以作参考。

Google Protocol Buffers 简称 Protobuf,它提供了一种灵活、高效、自动序列化结构数据的机制,可以联想 XML,但是比 XML 更小、更快、更简单。仅需要自定义一次你所需的数据格式,然后用户就可以使用 Protobuf 编译器自动生成各种语言的源码,方便的读写用户自定义的格式化的数据。与语言无关,与平台无关,还可以在不破坏原数据格式的基础上,依据老的数据格式,更新现有的数据格式。

前后端交互方式

前后端都是以二进制形式进行交互信息。前后端定义proto后缀的文件,以此文件来当文档来进行沟通。

protobuf文件形式

以下为protobuf文件的demo,test.proto,文件的结构确实简单明了。

enum FOO {
  BAR = 1;
}

message Test {
  required float num  = 1;
  required string payload = 2;
  optional string payloads = 3;
}

message AnotherOne {
  repeated FOO list = 1;
}
前后端进行protobuf的环境安装

后端以node为例子:
安装bufferhelper以及protocol-buffers进行解析protobuf文件

npm install bufferhelper
npm install protocol-buffers

前端需要安装解析protobuf的环境。
mac使用brew安装protobuf环境。此操作需要先安装Homebrew环境。具体的Homebrew的安装自行搜索。
windows的前端环境安装有点不一样,自行搜索。

brew install protobuf

测试前端proto环境是不是安装好了,如果有版本就是安装好了。

protoc --version

在进行前后端交互之前,前端需要进行编译proto文件。
test.proto为前端以及后端相同的proto文件。先编译为js文件再执行。首先进入node项目的proto的目录下面,执行下面的命令之后会生成test_pb.js文件。最后js只需要解析这个文件即可。前端也需要执行这样的操作,因为我这边是前后端分离的。是两个项目,所以两个项目都需要编译。

protoc --js_out=import_style=commonjs,binary:. test.proto
后端给前端传数据

后端赋值proto文件的内容并传给前端。
后端传protobuf二进制给前端,要先转化为json才可以给前端。不然的话前端会转化成乱码的。前端需要请求此路由。

app.get("/proto/get", function (req, res) {
  let protobuf = require("protocol-buffers")
  let messages=protobuf(fs.readFileSync("./proto/test.proto")
  let buf = messages.Test.encode({
    num: 42,
    payload: "hello world node js and javahhh呵呵呵",
    payloads: ""
  })
  console.log(buf) // 打印出来的是二进制流
  res.send(JSON.stringify(buf)); //需要进行json化然后给前端。不然的话浏览器会自动解析成文字的
})

前端需要进行接受二进制流
先引入proto.js文件以及protobufjs插件

  import awesome from "../../proto/test_pb.js"

前端用axios请求/proto/get的路由,在回调函数里的res.data为后端的返回值。进行以下操作。打印出来的message3也是解析好的文件。

 axios({
      method:"get",
      url: "/proto/get",
      headers: { "contentType":"application/x-protobuf"} }).then(res => {
      let message3 = awesome.Test.deserializeBinary(res.data.data)
      let nums = message3.getNum()
      console.log(nums) // nums=42。解析出来就是后端传过来的42
      let pm = awesome.Test.deserializeBinary(res.data.data)
      let protoBuf = pm.toObject()
      console.log("protoBuf: ", protoBuf) // 打印出来是一个对象
    }).catch((error) => {
      console.log(error)
    })
前端给后端传数据

前端需要进行proto文件的赋值以及转换为二进制给后端
引入需要依赖的文件。

  import awesome from "../../proto/test_pb.js"
  import protobuf from "protobufjs"
     let message = new awesome.Test() // 调用Person对象  实例化
    // 赋值
    message.setNum(23)
    message.setPayload("asd")
    // 序列化
    let bytes = message.serializeBinary() //  字节流
    let blob = new Blob([bytes], {type: "buffer"});
    axios({
      method:"post",
      url: "/proto/send",
      data: blob,
      headers: {
        "Content-Type": "application/octet-stream" // 这里根据后台要求进行设置的,如果没有要求应该是 application/octet-stream (二进制流)
      }
    }).then(res => {
      console.log(res)
    }).catch((error) => {
      console.log(error)
    })

后端需要接受文件
引入文件

let BufferHelper = require("bufferhelper");

接收字节流的代码

app.post("/proto/send", function (req, res) {
  let bufferHelper = new BufferHelper();
  req.on("data", function (chunk) {
    bufferHelper.concat(chunk);
  });
  req.on("end", function () {
    let protobuf = require("protocol-buffers")
    let buffer = bufferHelper.toBuffer();
    console.log(buffer) // 这里已经就是二进制文件了
    let message3 = awesome.Test.deserializeBinary(buffer)
    console.log(message3.getNum()) // 打印的就是前端传的23
    let pm = awesome.Test.deserializeBinary(buffer)
    let protoBuf = pm.toObject()
    console.log(protoBuf) // 打印的是{ num: 23, payload: "asd", payloads: "asds" }
    console.log(protoBuf.num) // 打印23
  });
})

以上就是关于protobuf的前后交互。如有错误,请指出。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101702.html

相关文章

  • 精读《REST, GraphQL, Webhooks, & gRPC 如何选型》

    摘要:而利用进一步提高了序列化速度,降低了数据包大小。带来的最大好处是精简请求响应内容,不会出现冗余字段,前端可以决定后端返回什么数据。再次强调,相比和,是由前端决定返回结果的反模式。请求者可以自定义返回格式,某些程度上可以减少前后端联调成本。 1 引言 每当项目进入联调阶段,或者提前约定接口时,前后端就会聚在一起热火朝天的讨论起来。可能 99% 的场景都在约定 Http 接口,讨论 URL...

    DevWiki 评论0 收藏0
  • 带入gRPC:gRPC及相关介绍

    摘要:原文地址带入及相关介绍项目地址作为开篇章,将会介绍相关的一些知识。 原文地址:带入gRPC:gRPC及相关介绍 项目地址:go-grpc-example 作为开篇章,将会介绍 gRPC 相关的一些知识。简单来讲 gRPC 是一个 基于 HTTP/2 协议设计的 RPC 框架,它采用了 Protobuf 作为 IDL 你是否有过疑惑,它们都是些什么?本文将会介绍一些常用的知识和概念,更详...

    y1chuan 评论0 收藏0
  • 带入gRPC:gRPC及相关介绍

    摘要:带入及相关介绍原文地址带入及相关介绍项目地址作为开篇章,将会介绍相关的一些知识。 带入gRPC:gRPC及相关介绍 原文地址:带入gRPC:gRPC及相关介绍 项目地址:go-grpc-example 作为开篇章,将会介绍 gRPC 相关的一些知识。简单来讲 gRPC 是一个 基于 HTTP/2 协议设计的 RPC 框架,它采用了 Protobuf 作为 IDL 你是否有过疑惑,它们都...

    AJie 评论0 收藏0
  • 基于 protobuf 协议实现高性能的 IM 客户

    摘要:涉及到计算机基础知识,例如字节缓冲大小端等。是指用多少位表示的整数,例如就是用位即一个字节表示的整数,二进制范围是,对应的十进制就是。开发时通讯双方或者多方终端都遵循协议。 这里记录了使用 protobuf 协议与服务端数据交互的相关内容和知识。涉及到计算机基础知识,例如字节、buffer 缓冲、大小端等。 字节 / Byte 1 字节代表了 8 位(bit)二进制,1 位就是 0...

    ssshooter 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<