您当前的位置:首页 > 养生 > 内容

protobuf(protobuf 有哪些变量类型)

本文目录

  • protobuf 有哪些变量类型
  • protobuf 怎么在iOS中实用
  • 为什么Protobuf的默认序列化格式没有包含消息的长度与类型
  • protobuf安装好以后怎么用
  • 如何在Go中使用Protobuf
  • 如何生成arm64的protobuf库
  • 作为java后端,在用protobuf的情况下我该给前端传什么形式的数据
  • java 怎么使用protobuf库
  • protobuf 怎么查看版本
  • 为什么protobuf不支持int8这样的类型

protobuf 有哪些变量类型

要通信,必须有协议,否则双方无法理解对方的码流。在protobuf中,协议是由一系列的消息组成的。因此最重要的就是定义通信时使用到的消息格式。

 

Protobuf消息定义

消息由至少一个字段组合而成,类似于C语言中的结构。每个字段都有一定的格式。

字段格式:限定修饰符① | 数据类型② | 字段名称③ | = | 字段编码值④ | [字段默认值⑤]

①.限定修饰符包含 required\optional\repeated

 

Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。

Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。---因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。

Repeated:表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。

 

②.数据类型

 

Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型.

N 表示打包的字节并不是固定。而是根据数据的大小或者长度。

例如int32,如果数值比较小,在0~127时,使用一个字节打包。

关于枚举的打包方式和uint32相同。

关于message,类似于C语言中的结构包含另外一个结构作为数据成员一样。

关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高。根据项目的实际情况,一般选择fixed32,如果遇到对传输数据量要求比较苛刻的环境,可以选择int32.

③.字段名称

 

字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的。

protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName.

④.字段编码值

有了该值,通信双方才能互相识别对方的字段。当然相同的编码值,其限定修饰符和数据类型必须相同。

编码值的取值范围为 1~2^32(4294967296)。

其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低(相对于1-15),当然一般情况下相邻的2个值编码效率的是相同的,除非2个值恰好实在4字节,12字节,20字节等的临界区。比如15和16.

1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用。

protobuf 还建议把经常要传递的值把其字段编码设置为1-15之间的值。

消息中的字段的编码值无需连续,只要是合法的,并且不能在同一个消息中有字段包含相同的编码值。

建议:项目投入运营以后涉及到版本升级时的新增消息字段全部使用optional或者repeated,尽量不实用required。如果使用了required,需要全网统一升级,如果使用optional或者repeated可以平滑升级。

 

⑤.默认值。当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端。当接受数据是,对于optional字段,如果没有接收到optional字段,则设置为默认值。

 

关于import

protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。

关于package

避免名称冲突,可以给每个文件指定一个package名称,对于java解析为java中的包。对于C++则解析为名称空间。

 

关于message

支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息。

关于enum

枚举的定义和C++相同,但是有一些限制。

枚举值必须大于等于0的整数。

使用分号(;)分隔枚举变量而不是C++语言中的逗号(,)

eg.

enum VoipProtocol 

{

    H323 = 1;

    SIP  = 2;

    MGCP = 3;

    H248 = 4;

}

protobuf 怎么在iOS中实用

有两种方式,一是直接使用C++版, 引用.h和dylib就可以了, 用在64位的5s上很容易,但是在5以下的32位上编译环不容易弄对。二是用objc版的。可以参考如下操作:1,下载ProtocolBuffer包,并按照包中根目录下README.txt安装。make install后,会生成编译器protoc,并拷贝到/usr/local/bin目录下。2,下载Objective-C compiler for ProtocolBuffer。目前有两种类型的实现。一个针对ProtocolBuffer2.2做修改,使最后生成的.proto文件编译器(protoc)支持Objective-C类型的文件输出。它在这里:

为什么Protobuf的默认序列化格式没有包含消息的长度与类型

Protobuf 是经过深思熟虑的消息打包方案,它的默认序列化格式没有包含消息的长度与类型,自然有其道理。哪些情况下不需要在 protobuf 序列化得到的字节流中包含消息的长度和(或)类型?我能想到的答案有:如果把消息写入文件,一个文件存一个消息,那么序列化结果中不需要包含长度和类型,因为从文件名和文件长度中可以得知消息的类型与长度。如果把消息写入文件,一个文件存多个消息,那么序列化结果中不需要包含类型,因为文件名就代表了消息的类型。如果把消息存入数据库(或者 NoSQL),以 VARBINARY 字段保存,那么序列化结果中不需要包含长度和类型,因为从字段名和字段长度中可以得知消息的类型与长度。如果把消息以 UDP 方式发生给对方,而且对方一个 UDP port 只接收一种消息类型,那么序列化结果中不需要包含长度和类型,因为从 port 和 UDP packet 长度中可以得知消息的类型与长度。如果把消息以 TCP 短连接方式发给对方,而且对方一个 TCP port 只接收一种消息类型,那么序列化结果中不需要包含长度和类型,因为从 port 和 TCP 字节流长度中可以得知消息的类型与长度。如果把消息以 TCP 长连接方式发给对方,但是对方一个 TCP port 只接收一种消息类型,那么序列化结果中不需要包含类型,因为 port 代表了消息的类型。如果采用 RPC 方式通信,那么只需要告诉对方 method name,对方自然能推断出 Request 和 Response 的消息类型,这些可以由 protoc 生成的 RPC stubs 自动搞定。对于最后一点,比方说 sudoku.proto 定义为:service SudokuService {rpc Solve (SudokuRequest) returns (SudokuResponse);}那么 RPC method Sudoku.Solve 对应的请求和响应分别是 SudokuRequest 和 SudokuResponse。在发送 RPC 请求的时候,不需要包含 SudokuRequest 的类型,只需要发送 method name Sudoku.Solve,对方自知道应该按照 SudokuRequest 来解析(parse)请求。这个例子来自我的半成品项目 evproto。对于上述这些情况,如果 protobuf 无条件地把长度和类型放到序列化的字节串中,只会浪费网络带宽和存储。可见 protobuf 默认不发送长度和类型是正确的决定。Protobuf 为消息格式的设计树立了典范,哪些该自己搞定,哪些留给外部系统去解决,这些都考虑得很清楚。只有在使用 TCP 长连接,且在一个连接上传递不止一种消息的情况下(比方同时发 Heartbeat 和 Request/Response),才需要我前文提到的那种打包方案。(为什么要在一个连接上同时发 Heartbeat 和业务消息?请见陈硕《分布式系统的工程化开发方法》 p.51 心跳协议的设计。)这时候我们需要一个分发器 dispatcher,把不同类型的消息分给各个消息处理函数,这正是本文的主题之一。

protobuf安装好以后怎么用

下载protobuf 文件,自行百度解压tar -zxvf protobuf-2.5.0.tar.gz编译/安装cd protobuf-2.5.0(可以参考README思路来做。)./configuremakemake check (check结果可能会有错误,但不用管她,因为暂时那些功能用不到)make install(完了之后会在 /usr/local/bin 目录下生成一个可执行文件 protoc)检查安装是否成功protoc --version如果成功,则会输出版本号信息。如果有问题,则会输出错误内容错误及解决方法 :protoc: error while loading shared libraries: libprotoc.so.8: cannot open shared 错误原因: protobuf的默认安装路径是/usr/local/lib,而/usr/local/lib 不在Ubuntu体系默认的 LD_LIBRARY_PATH 里,所以就找不到该lib 解决方法: 1). 创建文件 /etc/ld.so.conf.d/libprotobuf.conf,在该文件中输入如下内容: /usr/local/lib 2). 执行命令 sudo ldconfig

如何在Go中使用Protobuf

Protobuf对于Golang通过插件进行支持,因些需要安装protoc的执行环境,下面我们来一步步看下,如何搭建一个编译环境。1. 安装protoc2. 下载并安装protobuf-Go插件从github上下载插件,并解压(https://github.com/golang/protobuf),得到以下的目录[plain] view plain copydrwxr-xr-x 6 root root 4096 Jun 16 15:45 . drwxr-xr-x 3 root root 4096 Jun 16 15:48 .. -rw-r--r-- 1 root root 173 Jun 15 06:31 AUTHORS -rw-r--r-- 1 root root 170 Jun 15 06:31 CONTRIBUTORS drwxr-xr-x 3 root root 4096 Jun 15 06:31 jsonpb -rw-r--r-- 1 root root 1583 Jun 15 06:31 LICENSE -rw-r--r-- 1 root root 2080 Jun 15 06:31 Makefile -rw-r--r-- 1 root root 1955 Jun 15 06:31 Make.protobuf drwxr-xr-x 4 root root 4096 Jun 15 06:31 proto drwxr-xr-x 7 root root 4096 Jun 16 15:42 protoc-gen-go drwxr-xr-x 8 root root 4096 Jun 15 06:31 ptypes -rw-r--r-- 1 root root 7149 Jun 15 06:31 README.md 这时,执行make install,多半是不会成功的,一般会报找不到对应的文件,原因在于go源文件中指定的目录位置是这样的

如何生成arm64的protobuf库

1、下载 protobuf-2.5.0-mast ,并解压2、在解压后的 目录内部建立一个 目录 名字随便写,我这里写的 是 xcodeProject 如图:3、新建一个 静态库工程 在刚才 的 xcodeProject 文件夹内.4,将工程中 自带的 哪个 类 删除 ,也就是删除 下图 中 的 protobufXcode6 那个类 。5, 将 protobuf-2.5.0-master/src/google 文件夹 添加到 刚才新建的 静态库工程 中 ,注意 不需要 勾选 copy 复选框,注意勾选add to target ,如图 。6、 将 google/protobuf/compiler/文件夹 从工程中 移除 。7、 将 google 中所有的 test 文件 删除 ,可在 文件中 搜 test 如图 ,然后 删除 google 文件夹中 包含 test 的文件 如图。8、添加 头文件 引用 路径,如图。9、生成 config.h 头文件 。 打开终端 , cd 到 protobuf 跟目录下 , 运行 ./configure 脚本 就可以生成 config.h 文件 ,生成后 将 config.h 文件 添加到 xcode 工程 中

作为java后端,在用protobuf的情况下我该给前端传什么形式的数据

protobuf是你们落地时存储的数据格式,跟给前端的格式是没有关系的。可以通过工具类直接转json后传给前端。Class《?》 clazz = Class.forName(className);Method method = clazz.getMethod(“parseFrom“, byte.class);JsonFormat().printToString((GeneratedMessage) method.invoke(clazz, bytes));其中className是你根据protobuf文件生成的java类,bytes是读取的protobuf对象的字节数组。

java 怎么使用protobuf库

1.到注意的就是2点:1.不能用statement,否则无法插入blob类型的数据2.为参数赋值时,要用ByteArrayInputStream stream = new ByteArrayInputStream(result); ps.setBinaryStream(1,stream,stream.available());

protobuf 怎么查看版本

protobuf版本需要在protobuf程序中查看。

在protobuf程序中查看版本步骤如下所示:

1、点击打开计算机,进入分区列表。

2、在计算机分区列表中选择protobuf程序所在的文件夹。

3、点击打开protobuf程序。

4、如图所示在protobuf程序中,即可完成protobuf版本查看。

为什么protobuf不支持int8这样的类型

1 protobuf不是专为c、cplusplus而生的,它还得为java、python等语言服务,而这些语言中没有int16的概念。2 另protobuf采用变长整型编码,字节的最高位用于标识后头还有无一体字节(表示同一个整数),低七位存储实际值。可几乎不增加时间复杂度,有效提高压缩率。


声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,谢谢。

上一篇: domesticated(做家务用英语怎么说)

下一篇: 网页制作视频教程(零基础怎么学习网页制作)



猜你感兴趣

推荐阅读

网站内容来自网络,如有侵权请联系我们,立即删除! | 软文发布 | 粤ICP备2021106084号