ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

protocol buffer 基础

2020-07-05 22:05:31  阅读:232  来源: 互联网

标签:info protocol proto buffer 基础 phone message foo id


我们知道接口传输数据的格式有XML,它是 web services 使用的传输数据的格式,在web services 中叫 WSDL。

https://www.w3school.com.cn/wsdl/index.asp

不过 web Services 已经是被淘汰的技术了。

现在更是主流的是使用JSON作为数据传输格式。HTTP + JSON是黄金搭档。

什么是protocol buffer

protocol buffer是一种与语言和平台无关。

Protocol Buffer是用于结构化数据串行化的灵活、高效、自动的方法,有如XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。

protocol buffer 是如何使用

  • 定义 xx.proto文件,即 接口数据格式。
  • 使用 proto 命令生成对应语言脚本。
  • 通过语言脚本设置接口要发送/接收的数据。

定义 .proto 文件,

创建一个foo.proto 文件中定义你需要做串行化的数据结构信息。每个ProtocolBuffer信息是一小段逻辑记录,包含一系列的键值对。

这里定义一个简单的 foo.proto 文件定义了个人信息:

syntax = "proto2";
package info;

message Person {
    required string name=1;
    required int32 id=2;
    optional string email=3;

    enum PhoneType {
        MOBILE=0;
        HOME=1;
        WORK=2;
    }

    message PhoneNumber {
        required string number=1;
        optional PhoneType type=2 [default=HOME];
    }

    repeated PhoneNumber phone=4;
}

这个信息就是你的接口要发送的数据格式。

文件说明:

syntax = "proto2";

文件最开始建议说明使用proto2还是proto3语法的声明。

package info;

文件必须以 package xxxx; 声明开头,作为协议唯一的标识,避免不同项目的命名冲突,你可以理解成我给一个人起名叫张三,如果要想找这个人,就要叫一声张三。

message Person {
    ...
    message PhoneNumber {
        ...
    }
}

一个 message 相当于一个指定类型的集合,例如 bool, int32, float, double ,string 这些类型都是可以直接使用在proto协议中的某个message当中指定数据类型的。

一个message可以直接嵌套另一个message使用,被嵌套的message就相当于string一样,被认为是一种数据类型。

required string name=1;
required int32 id=2;
optional string email=3;
...
repeated PhoneNumber phone=4;

每个message的字段必须要声明是requiredrepeatedoptional

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

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

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

好了,你现在对 .proto 文件的定义有了大概的一个了解了。

使用 proto 命令生成对应语言脚本

1、下载 protobuf 文件

https://github.com/protocolbuffers/protobuf/releases

以windows为例,下载下面两个文件:

  • protobuf-python-3.12.3.zip

  • protoc-3.12.3-win64.zip

2、 先解压 protobuf-python-3.12.3.zip 文件,得到 protobuf-3.12.3目录,再解压 protoc-3.12.3-win64.zip 文件得到 protoc 目录,把你 protoc 目录放到 protobuf-3.12.3目录。

3、 设置环境变量path

D:\pybase\protobuf-3.12.3\protoc\bin

将上面的路径添加环境变量。

4、 执行 proto 命令,生成python脚本。利用前面创建 foo.proto 文件。

protoc --python_out=. foo.proto

你会看到同目录下多出一个 foo_pb2.py 的文件。不用打开看了,反正你也看不懂。

通过语言脚本设置接口要发送/接收的数据

现在我们利用 foo_pb2.py 文件定义发送的接口数据。 创建一个test_foo_pb2.py文件。

import foo_pb2


def set_info(info_):
    info_.id = 1
    info_.name = "tom"
    info_.email = "tom@gmail.com"

    phone = info_.PhoneNumber
    phone.phone = 400100
    phone.type = 2

    return info_


info = foo_pb2.Person()

one_info = set_info(info)
print("设置数据:\n", one_info)

proto_info = one_info.SerializeToString()
print("序列化:\n", proto_info)


def get_info(wanted_info):
    """
    反序列化的数据
    """
    print("反序列化:\n")
    wanted_id = wanted_info.id
    print("info id:", wanted_id)
    print("his age: ", wanted_info.name)

    print("his phone number :", wanted_info.PhoneNumber.phone)
    print("his phone type :", wanted_info.PhoneNumber.type)


first_parsed = foo_pb2.Person()
first_parsed.ParseFromString(proto_info)
get_info(first_parsed)

打印结果:

设置数据:
 name: "tom"
id: 1
email: "tom@gmail.com"

序列化:
 b'\n\x03tom\x10\x01\x1a\rtom@gmail.com'
 
反序列化:
info id: 1
his age:  tom
his phone number : 400100
his phone type : 2

我帮你问:这有什么用?

想想当你在发送数据的时候,以 序列化的数据发送,是不是更节省资源?是不是更安全?

标签:info,protocol,proto,buffer,基础,phone,message,foo,id
来源: https://www.cnblogs.com/fnng/p/13252078.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有