• protocol buffer 基础


    我们知道接口传输数据的格式有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:pybaseprotobuf-3.12.3protocin
    

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

    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("设置数据:
    ", one_info)
    
    proto_info = one_info.SerializeToString()
    print("序列化:
    ", proto_info)
    
    
    def get_info(wanted_info):
        """
        反序列化的数据
        """
        print("反序列化:
    ")
        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'
    x03tomx10x01x1a
    tom@gmail.com'
     
    反序列化:
    info id: 1
    his age:  tom
    his phone number : 400100
    his phone type : 2
    

    我帮你问:这有什么用?

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

  • 相关阅读:
    着迷英语900句总结
    SQL Server 常见数据类型
    SQL Server视频总结
    第三次SLA文档学习
    Rosetton Stone Summary
    【周总结】2018-10-19—2018-11-25
    学生信息管理系统总结
    VB中 EOF 和 BOF 的区别
    VB中 On error 的用法
    VB中 . 与 ! 的区别
  • 原文地址:https://www.cnblogs.com/fnng/p/13252078.html
Copyright © 2020-2023  润新知