protobuf介绍由于网上关于protobuf交互的资料比较零散,所以整理了一下protobuf前后端交互的资料以供参考。GoogleProtocolBuffers,简称Protobuf,提供了一种灵活、高效、自动的结构化数据序列化机制。它可以与XML相关联,但它比XML更小、更快、更简单。您只需要自定义一次您需要的数据格式,之后用户就可以使用Protobuf编译器自动生成各种语言的源代码,方便的读写用户自定义格式的数据。与语言和平台无关,可以在不破坏原有数据格式的情况下,根据旧的数据格式更新已有的数据格式。前后端交互方式前后端都以二进制形式交换信息。前后端定义了proto后缀的文件,并以此文件作为通信的文档。下面的protobuf文件格式是protobuf文件test.proto的demo。文件的结构非常简单明了。枚举FOO{BAR=1;}消息测试{需要floatnum=1;所需的字符串有效负载=2;optionalstringpayloads=3;}messageAnotherOne{repeatedFOOlist=1;}前后端protobuf环境安装后端以Node为例:安装bufferhelper和protocol-buffers解析protobuf文件npminstallbufferhelpernpminstallprotocol-buffers前端需要安装解析protobuf的环境。Mac使用brew安装protobuf环境。此操作需要先安装Homebrew环境。具体的Homebrew安装自行搜索。windows的前端环境安装有点不一样,自行搜索。brewinstallprotobuf测试前端proto环境是否安装,有版本则安装。protoc--version在前后端交互之前,前端需要编译proto文件。test.proto是前后端同一个proto文件。先编译成js文件,然后执行。首先进入node项目的proto目录,执行以下命令后会生成test_pb.js文件。最后js只需要解析这个文件即可。前端也需要进行这样的操作,因为我这边是前后端分离的。是两个项目,所以两个项目都需要编译。协议--js_out=import_style=commonjs,binary:.test.proto后端向前端传输数据后端分配proto文件的内容并传递给前端。后端将protobufbinary传给前端,必须转成json后才能传给前端。否则前端会转换成乱码。前端需要请求这条路由。app.get('/proto/get',function(req,res){letprotobuf=require('protocol-buffers')letmessages=protobuf(fs.readFileSync('./proto/test.proto')letbuf=messages.Test.encode({num:42,payload:'helloworldnodejsandjavahhhhehehe',payloads:''})console.log(buf)//输出为二进制流res.send(JSON.stringify(buf));//需要json化后给前端,否则浏览器会自动解析成文本})前端需要接受二进制流先导入proto.js文件和protobufjs插件-inimportawesomefrom'../../proto/test_pb.js'前端使用axios请求/proto/get路由,回调函数中的res.data为后端的返回值。执行以下操作,打印出来的message3也是解析后的文件。axios({method:'get',url:'/proto/get',headers:{'contentType':'application/x-protobuf'}}).then(res=>{letmessage3=awesome.Test.deserializeBinary(res.data.data)letnums=message3.getNum()console.log(nums)//nums=42.从后端解析出来是42letpm=awesome.Test.deserializeBinary(res.data.data)letprotoBuf=pm.toObject()console.log('protoBuf:',protoBuf)//打印出来是一个对象}).catch((error)=>{console.log(error)})frontendtobackend前端传输数据的时候,需要给proto文件赋值,转成二进制,给后端引入依赖文件。importawesomefrom'../../proto/test_pb.js'importprotobuffrom'protobufjs'letmessage=newawesome.Test()//调用Person对象实例化//赋值message.setNum(23)message.setPayload('asd')//序列化letbytes=message.serializeBinary()//字节流letblob=newBlob([bytes],{type:'buffer'});axios({method:'post',url:'/proto/send',data:blob,headers:{'Content-Type':'application/octet-stream'//这个根据后台要求设置,如果没有要求,应该是application/octet-stream(binarystream)}}).then(res=>{console.log(res)}).catch((error)=>{console.log(error)})后端需要接受文件导入文件letBufferHelper=require('bufferhelper');接收字节流的代码;});req.on('end',function(){letprotobuf=require('protocol-buffers')letbuffer=bufferHelper.toBuffer();console.log(buffer)//这已经是二进制文件了letmessage3=awesome.Test.deserializeBinary(buffer)console.log(message3.getNum())//打印的是前端发送的23letpm=awesome.Test.deserializeBinary(buffer)letprotoBuf=pm.toObject()console.log(protoBuf)//打印出来的是{num:23,payload:'asd',payloads:'asds'}console.log(protoBuf.num)//print23});})以上就是protobuf的交互。如有错误,请指出。
