tnblog
首页
视频
资源
登录

grpc Protocol Buffer 消息定义

8451人阅读 2020/3/23 17:25 总访问:3757978 评论:0 收藏:1 手机
分类: grpc

 标量类型

gRPC

 

   数值型 有很多种形式: double, foat, fint32, int64, uint32, uint64, sint32, sint64, fixed32, fixed 64, sfixed32, sfixed64根据需要选择对应的数值类型。

   布尔型 bool型可以有 True 和 False 两个值。

   字符串 string=表示任意长度的文本,但是它必须包含的是UTF-8编码或7位ASCI的文本,长度不可超过232。

   字节型 bytes可表示任意的byte数组序列,但是长度也不可以超过232,最后是由你来决定如何解释这些 bytes。例如你可以使用这个类型来表示一个图片。



实践 (一)

  1. 创建文件 person.proto



   2. 编写脚本内容如下

  1. syntax = "proto3";
  2. message Person{
  3.     int32 id = 1;
  4.     string name = 2;
  5.     float height = 3;
  6.     float weight = 4;
  7.     bytes avatar = 5;
  8.     string email = 6;
  9.     bool email_verified = 7;
  10. }


  解释字段数值 (Tag) (也就是这些1,2,3,4,5,...)


在 Protocol Buffers里面,字段的名其实没那么重要,但是写C#代码的时候,字段名还是很重要的。

对于protobuf来说,这个tag是更为重要的。

可以使用的最小的tag数量值是1,最大值是2^29-1,或者536,870,911。但是你不可以使用19000到19999之间的数,这部分是保留的。

还有值得注意的一点的是:

从1到15的Tag数只占用1个字节的空间,所以他们应该被频繁使用的字段。而从16到2047,则占用两个字节,它们可以用在不频繁使用的字段上。~~




 字段规则


 protobufe的字段必须满足以下两个规则之一:

   单数字段( Singular)

   大概意思就是指这个字段只能出现0或1次(不能超过一次),这也是 proto3的默认字段规则。

   重复字段( Repeated)

   与 singular相对的就是 repeated。如果你想做一list或数组的话,你可以使用重复字段这个概念。这个Iist可以有任何数量(包括0)的元素。它里面的值的顺序将会得到保留。



3.添加相关代码

  1. syntax = "proto3";
  2. // 定义Person的消息
  3. message Person{
  4.     int32 id = 1;
  5.     string name = 2;
  6.     float height = 3;
  7.     float weight = 4;
  8.     bytes avatar = 5;
  9.     string email = 6;
  10.     bool email_verified = 7;
  11.     repeated string phone_numbers = 8; // packed
  12. }


  保留的字段


 如果你对你定义的消息类型进行了更新,例如删除某个字段或者注释某个字段,那么其他开发者在以后更新这个消息类型的时候可能会重新使用你删除/注释掉的字段的数值(tag)。

   如果以后还需要使用这个消息类型的老版本的proto文件,南无这将引起严重的问题,例如数据损坏,隐私漏洞等等。

   

   那么一种避免此类事情发生的解决办法就是将你删除/注释掉的这些字段的数值(或/并且包括字段名,因为字段名可引起JSON序列化的问题)标记为reserved,如果其他人再使用,

   这个数值作为字段标识符,那么编译器就会有错误提示。



4.添加相关代码

  1. syntax = "proto3";
  2. // 定义Person的消息
  3. message Person{
  4.     int32 id = 1;
  5.     string name = 2;
  6.     float height = 3;
  7.     float weight = 4;
  8.     bytes avatar = 5;
  9.     string email = 6;
  10.     bool email_verified = 7;
  11.     repeated string phone_numbers = 8; // packed
  12.     //string foo = 8;
  13.     reserved 9, 10, 20 to 100, 200 to max; //保留数值
  14.     reserved "foo","bar"; //保留字段名
  15. }


如果我们这里把foo的注释去掉就会报错!!!


  字段的默认值


 当消息被解析的时候,如果编码的消息里不含有特定的一个 singular元素,那么在被解析对象里相应的字段就会被设为默认值。

   常用类型的默认值如下:


  • string: 空字符串

  • bytes: 空的byte数组

  • bool: false

  • 数值型: 0

  • 枚举enum:枚举里定义的第一个枚举值,值必须是0

  • repeated:通常是相应开发语言里的空list

  • 还有个消息类型的字段,它的默认值和开发语言有关,这个以后再说。





    枚举类型 tag值必须从0开始

    1. syntax = "proto3";
    2. // 定义Person的消息
    3. message Person{
    4.     int32 id = 1;
    5.     string name = 2;
    6.     float height = 3;
    7.     float weight = 4;
    8.     bytes avatar = 5;
    9.     string email = 6;
    10.     bool email_verified = 7;
    11.     repeated string phone_numbers = 8; // packed
    12.     Gender gender = 11;
    13.     //string foo = 8;
    14.     reserved 9, 10, 20 to 100, 200 to max; //保留数值
    15.     reserved "foo","bar"; //保留字段名
    16.     enum Gender{
    17.         NOT_SPECIFIED = 0;
    18.         FEMALE = 1;
    19.         MALE = 2;
    20.     }
    21. }


    添加相关配置可以重名

    1.     enum Gender{
    2.         option allow_alias = true;
    3.         NOT_SPECIFIED = 0;
    4.         FEMALE = 1;
    5.         WOMAN = 1;
    6.         MALE = 2;
    7.         MAN = 2;
    8.     }



    自定义类型的创建

    1.     Date birthday = 12;
    2.     enum Gender{
    3.         option allow_alias = true;
    4.         NOT_SPECIFIED = 0;
    5.         FEMALE = 1;
    6.         WOMAN = 1;
    7.         MALE = 2;
    8.         MAN = 2;
    9.         reserved 3, 10, 20 to 100, 200 to max; //保留数值
    10.         reserved "foo","bar"; //保留字段名
    11.     }
    12. }
    13. message Date {
    14.     int32 year = 1;
    15.     int32 month = 2;
    16.     int32 day = 3;
    17. }


    当然也可以复制出来,到创建一个新的 data.proto


    代码如下:

    1. syntax = "proto3";
    2. message Date {
    3.     int32 year = 1;
    4.     int32 month = 2;
    5.     int32 day = 3;
    6. }


    然后导入进来

    1. import "data.proto";



    打包

    打包相当于命名空间一样

    1. package my.project;


    如果希望 C# 的命名空间有所不一样的化可以再添加一条命令

    1. option csharp_namespace = "My.WebApis";



    最后编译 proto 文件

    打开下面的地址:

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


    选择版本



    然后


    来到目录文件夹下,生成C#的代码


    看一下生成的文件


    最后来一个一次性生成文件

    1. protoc .\*.proto --csharp_out=csharp















    欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

    评价
    这一世以无限游戏为使命!
    排名
    2
    文章
    665
    粉丝
    44
    评论
    93
    docker中Sware集群与service
    尘叶心繁 : 想学呀!我教你呀
    一个bug让程序员走上法庭 索赔金额达400亿日元
    叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
    .net core 塑形资源
    剑轩 : 收藏收藏
    映射AutoMapper
    剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
    ASP.NET Core 服务注册生命周期
    剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
    ICP备案 :渝ICP备18016597号-1
    网站信息:2018-2025TNBLOG.NET
    技术交流:群号656732739
    联系我们:contact@tnblog.net
    公网安备:50010702506256
    欢迎加群交流技术