在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
google-protobuf 官网地址 https://developers.google.com/protocol-buffers/
网上有些封装过后支持前端使用的 google-protobu f库,比如 protobufjs ,不过看了下不太喜欢... 感觉就还是使用 google-protobuf 官网提供的比较舒心!
一、安装protoc编译器官网下载地址:https://github.com/protocolbuffers/protobuf/releases 打开网址:
下拉:
下载对应系统的压缩包!并且版本为protoc-3.*的,另外一个系列貌似没有编译为js的模块
下载 protoc-3.14.0-win64.zip (对应自己的系统),解压,进入 bin 文件夹就发现 protoc.exe 文件了:
查看可编译的输出类型语言: protoc -h 翻到最下面 --cpp_out=OUT_DIR Generate C++ header and source. --csharp_out=OUT_DIR Generate C# source file. --java_out=OUT_DIR Generate Java source file. --js_out=OUT_DIR Generate JavaScript source. --kotlin_out=OUT_DIR Generate Kotlin file. --objc_out=OUT_DIR Generate Objective-C header and source. --php_out=OUT_DIR Generate PHP source file. --pyi_out=OUT_DIR Generate python pyi stub. --python_out=OUT_DIR Generate Python source file. --ruby_out=OUT_DIR Generate Ruby source file. js_out,就是 js ,没有的就不支持。 现在就可以用这个 protoc.exe 编译文件了。可以每次进到这个目录执行,也可以加入环境变量,就可以在自己的项目编辑器里面直接使用。
二、根据 *.proto 文件,编译为对应语言的文件直接在目录位置输入 cmd 然后回车 打开在当前目录的命令行工具
输入编译命令: protoc *.proto --js_out=import_style=commonjs,binary:./pb
说明:
*.proto 选中当前目录的所有后缀为 .proto 的文件(也可以具体的某一个文件)。如果没有进到 *.proto 文件所在的目录,也可以加上路 劲:../path1/*.proto 这种。但是如果proto之间有相互引用,就不要加路劲了,引用会报错。
--js_out 编译目标为 js 文件
commonjs 编译出来的 js 文件,按照 commonjs 导入使用
binary:./proto-js 编译的输出目录,就是个相对路径。例如一个点:binary:. 直接编译到当前目录。文件多的时候建一个文件夹(提前建好)来放比较安逸
只要没报错就编译完成了:
三、导入使用按照前面的 commonjs 规范,使用 require 导入:
(proto源文件可能在编辑器里会飘红报错,不用管它...) 嗯...使用前先: npm i google-protobuf 看一下都有些啥:
里面包含了对应 .proto 文件所定义的数据结构。它们都挂载有相同的方法,可以看编译出来的js文件:
解密数据:deserializeBinary 内部调用的 deserializeBinaryFromReader 方法 加密数据:serializeBinary 内部调用的 serializeBinaryToWriter 方法
主要目标:
具体例子: let proto = require("../pb/conn.int_pb"); const protoObj = new proto.Image()//以 new 的方式创建 console.log(protoObj)//输出一个对象 可以看到有一个array属性 array: [] 其实所有的属性值就会放里面,没设置时是空的 //设置对应的属性 (自己确定好属性值的类型) protoObj.setId('123') protoObj.setWidth(88) protoObj.setUrl('123') console.log(protoObj)//可以看到设置的值 array: [ '123', 88, 88, '123' ] const protoData = protoObj.serializeBinary()//加密 console.log(protoData)//一串Uint8Array数组值 protobuf 加密过后都是 Uint8Array 类型的数据 const newProtoObj = proto.Image.deserializeBinary(protoData)//解密 必须以对应的数据结构调用方法 传入数据 console.log(newProtoObj)//和 protoObj 数据就一样了 console.log(newProtoObj.getId())// "123" console.log(newProtoObj.getWidth())// 88 console.log(newProtoObj.getHeight())// 0 存在的属性 但是前面没有赋值 console.log(newProtoObj.getUrl())// "123" console.log(newProtoObj.getThumbnailUrl())// "" 存在 但是前面没有赋值 是个空串 // console.log(newProtoObj.getTThumbnailUrl())//不存在的属性 报错 TypeError: newProtoObj.getTThumbnailUrl is not a function //不存在的属性都会报错,存在的属性都会有对应的默认值 //可以看出来,默认是每个属性都有对应的 get、set方法
四、打包整合为对应自己 proto 格式的 jssdk现在使用的是编译出来的多个 js 源文件,可以利用 nodejs 打包成一个 js 文件。项目使用的一个 go 语言编写的 IM 服务,使用了 GRPC 和 protobuf ,打包成一个 JS 文件其实就是对应 IM 服务的 JSSDK 了。 安装打包工具 browserify ,或者简单配置一个 webpack 打包 npm install -g browserify
打包 browserify source_pb.js > im_sdk.js 打包的时候需要 安装有 google-protobuf ,_pb.js 有引用,打包完成 sdk 比所有的 _pb.js 加起来还大,但是在项目里使用不需要安装 google-protobuf 包了。
五、小程序使用在小程序使用的时候遇到两个报错,一个是 编译的时候 proto undefined, 一个是 socket.send 时 unknown data。 1、proto undefined 查资料说是小程序本身没有支持 protobuf,可以使用其他库来支持,乱七八糟的很多东西...。 感觉太麻烦,就想了个办法:我给它一个 proto。很简单,在 protoc.exe 编译好JS 文件里面声明一个 proto 就好了,如果是多个编译出的文件,可以再新建一个js文件 导出一个 proto ,再都导入引用它就好,目前没发现有啥问题。 2、socket.send 时 unknown data 小程序的send方法只接受 string、arraybuffer 类型数据,proto 加密过后是 Uint8Array 嘛,转成 arraybuffer 就号。Uint8Array.buffer 就得到 arraybuffer 。
|
请发表评论