Protobuf 语法

Protobuf语法

1.1.1. 基本规范

  • 文件以.proto做为文件后缀,除结构定义外的语句以分号结尾

  • 结构定义可以包含:message、service、enum

  • rpc方法定义结尾的分号可有可无

  • Message命名采用驼峰命名方式,字段命名采用小写字母加下划线分隔方式

      message SongServerRequest {
          required string song_name = 1;
      }
    
  • Enums类型名采用驼峰命名方式,字段命名采用大写字母加下划线分隔方式

      enum Foo {
          FIRST_VALUE = 1;
          SECOND_VALUE = 2;
      }
    
  • Service与rpc方法名统一采用驼峰式命名

1.1.2. 字段规则

  • 字段格式:限定修饰符 | 数据类型 | 字段名称 | = | 字段编码值 | [字段默认值]
  • 限定修饰符包含 required\optional\repeated
    • Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃
    • Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。—因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡
    • Repeated:表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值
  • 数据类型
    • Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型 img
    • N 表示打包的字节并不是固定。而是根据数据的大小或者长度
    • 关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高
  • 字段名称
    • 字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的
    • protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName
  • 字段编码值
    • 有了该值,通信双方才能互相识别对方的字段,相同的编码值,其限定修饰符和数据类型必须相同,编码值的取值范围为 1~2^32(4294967296)
    • 其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低,所以建议把经常要传递的值把其字段编码设置为1-15之间的值
    • 1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用
  • 字段默认值
    • 当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端

1.1.3. service如何定义

  • 如果想要将消息类型用在RPC系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer编译器会根据所选择的不同语言生成服务接口代码
  • 例如,想要定义一个RPC服务并具有一个方法,该方法接收SearchRequest并返回一个SearchResponse,此时可以在.proto文件中进行如下定义:
    service SearchService {
        rpc Search (SearchRequest) returns (SearchResponse) {}
    }
  • 生成的接口代码作为客户端与服务端的约定,服务端必须实现定义的所有接口方法,客户端直接调用同名方法向服务端发起请求,比较麻烦的是,即便业务上不需要参数也必须指定一个请求消息,一般会定义一个空message

1.1.4. Message如何定义

  • 一个message类型定义描述了一个请求或响应的消息格式,可以包含多种类型字段
  • 例如定义一个搜索请求的消息格式,每个请求包含查询字符串、页码、每页数目
  • 字段名用小写,转为go文件后自动变为大写,message就相当于结构体
    syntax = "proto3";

    message SearchRequest {
        string query = 1;            // 查询字符串
        int32  page_number = 2;     // 页码
        int32  result_per_page = 3;   // 每页条数
    }
  • 首行声明使用的protobuf版本为proto3
  • SearchRequest 定义了三个字段,每个字段声明以分号结尾,.proto文件支持双斜线 // 添加单行注释

1.1.5. 添加更多Message类型

  • 一个.proto文件中可以定义多个消息类型,一般用于同时定义多个相关的消息,例如在同一个.proto文件中同时定义搜索请求和响应消息
    syntax = "proto3";

    // SearchRequest 搜索请求
    message SearchRequest {
        string query = 1;            // 查询字符串
        int32  page_number = 2;     // 页码
        int32  result_per_page = 3;   // 每页条数
    }

    // SearchResponse 搜索响应
    message SearchResponse {
        ...
    }

1.1.6. 如何使用其他Message

  • message支持嵌套使用,作为另一message中的字段类型
    message SearchResponse {
        repeated Result results = 1;
    }

    message Result {
        string url = 1;
        string title = 2;
        repeated string snippets = 3;
    }

1.1.7. Message嵌套的使用

  • 支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息
  • 内部声明的message类型名称只可在内部直接使用
    message SearchResponse {
        message Result {
            string url = 1;
            string title = 2;
            repeated string snippets = 3;
        }
        repeated Result results = 1;
    }
  • 另外,还可以多层嵌套
    message Outer {                // Level 0
        message MiddleAA {        // Level 1
            message Inner {        // Level 2
                int64 ival = 1;
                bool  booly = 2;
            }
        }
        message MiddleBB {         // Level 1
            message Inner {         // Level 2
                int32 ival = 1;
                bool  booly = 2;
            }
        }
    }

1.1.8. proto3的Map类型

  • proto3支持map类型声明
    map<key_type, value_type> map_field = N;

    message Project {...}
    map<string, Project> projects = 1;
  • 键、值类型可以是内置的类型,也可以是自定义message类型
  • 字段不支持repeated属性

1.1.9. .proto文件编译

  • 通过定义好的.proto文件生成Java, Python, C++, Go, Ruby, JavaNano, Objective-C, or C# 代码,需要安装编译器protoc
  • 当使用protocol buffer编译器运行.proto文件时,编译器将生成所选语言的代码,用于使用在.proto文件中定义的消息类型、服务接口约定等。不同语言生成的代码格式不同:
    • C++: 每个.proto文件生成一个.h文件和一个.cc文件,每个消息类型对应一个类
    • Java: 生成一个.java文件,同样每个消息对应一个类,同时还有一个特殊的Builder类用于创建消息接口
    • Python: 姿势不太一样,每个.proto文件中的消息类型生成一个含有静态描述符的模块,该模块与一个元类metaclass在运行时创建需要的Python数据访问类
    • Go: 生成一个.pb.go文件,每个消息类型对应一个结构体
    • Ruby: 生成一个.rb文件的Ruby模块,包含所有消息类型
    • JavaNano: 类似Java,但不包含Builder类
    • Objective-C: 每个.proto文件生成一个pbobjc.h和一个pbobjc.m文件
    • C#: 生成.cs文件包含,每个消息类型对应一个类

1.1.10. import导入定义

  • 可以使用import语句导入使用其它描述文件中声明的类型
  • protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同,例如import “others.proto”;
  • protocol buffer编译器会在 -I / --proto_path参数指定的目录中查找导入的文件,如果没有指定该参数,默认在当前目录中查找

1.1.11. 包的使用

  • 在.proto文件中使用package声明包名,避免命名冲突
syntax = "proto3";
package foo.bar;
message Open {...}
  • 在其他的消息格式定义中可以使用包名+消息名的方式来使用类型,如
message Foo {
    ...
    foo.bar.Open open = 1;
    ...
}
  • 在不同的语言中,包名定义对编译后生成的代码的影响不同
    • C++ 中:对应C++命名空间,例如Open会在命名空间foo::bar中
    • Java 中:package会作为Java包名,除非指定了option jave_package选项
    • Python 中:package被忽略
    • Go 中:默认使用package名作为包名,除非指定了option go_package选项
    • JavaNano 中:同Java
    • C# 中:package会转换为驼峰式命名空间,如Foo.Bar,除非指定了option csharp_namespace选项

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/152785.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

conda环境下Tesseract:Failed loading language ‘eng‘问题解决

1 问题描述 使用Tesseract进行ocr文字识别&#xff0c;运行识别代码&#xff0c;报错如下&#xff1a; C:\Users\lishu\anaconda3\envs\pt2\python.exe D:/code/ptcontainer/opencv/car_reg.py Traceback (most recent call last): File "D:\code\ptcontainer\opencv\…

《QT从基础到进阶·三十三》QT插件开发QtPlugin

插件和dll区别&#xff1a; 插件 插件主要面向接口编程&#xff0c;无需访问.lib文件&#xff0c;热插拔、利于团队开发。即使在程序运行时.dll不存在&#xff0c;也可以正常启动&#xff0c;只是相应插件功能无法正常使用而已&#xff1b; 调用插件中的方法只要dll即可&#x…

【软件测试】接口测试中Post方法怎么测?

GET方法和POST方法传递数据的异同 http请求方法get和post是最常被用到的两个方法&#xff0c;get常用于向服务器请求数据&#xff0c;post常用于提交数据给服务器处理。 GET方法其实也可以传递少量的数据。 但它存在以下问题&#xff1a; 1)GET 方法不包含body&#xff0c;因此…

新手买电视盒子哪个好?数码粉实测电视盒子排名

新手们在买电视盒子时面对众多的品牌和机型&#xff0c;往往不知道电视盒子哪个好&#xff0c;我作为资深数码粉&#xff0c;已经买过十来款电视盒子了&#xff0c;近来某数码论坛公布了最新的电视盒子排名&#xff0c;我购入后进行了一周的深度实测&#xff0c;结果如何&#…

Java-整合OSS

文章目录 前言一、OSS 简介二、OSS 的使用1. Bucket 的创建与文件上传2. 创建 RAM 与用户授权3. 图形化管理工具-ossbrowser 三、Java 整合 OSS1. 基本实现2. 客户端直传 前言 最近公司的技术负责人让我整合下 OSS 到项目中&#xff0c;所以花了一点时间研究了下 OSS&#xff…

Redis内存淘汰机制

Redis内存淘汰机制 引言 Redis 启动会加载一个配置&#xff1a; maxmemory <byte> //内存上限 默认值为 0 (window版的限制为100M)&#xff0c;表示默认设置Redis内存上限。但是真实开发还是需要提前评估key的体量&#xff0c;提前设置好内容上限。 此时思考一个问题…

高质量发展项目——党务工作者能力提升培训在京成功举办

2021年6月&#xff0c;国务院办公厅印发了《关于推动公立医院高质量发展的意见》。为认真贯彻落实公立医院党建工作重点任务&#xff0c;加强公立医院党建&#xff0c;健全现代医院管理制度&#xff0c;实行党委领导下的院长负责制。发挥院级党组织把方向、管大局、作决策、促改…

flutter仿支付宝余额宝年化收益折线图

绘制: 1.在pubspec.yaml中引入:fl_chart: 0.55.2 2.绘制: import package:jade/utils/JadeColors.dart; import package:util/easy_loading_util.dart; import package:fl_chart/fl_chart.dart; import package:flutter/material.dart; import package:flutter_screenutil/…

MySQL分页查询的工作原理

前言 MySQL 的分页查询在我们的开发过程中还是很常见的&#xff0c;比如一些后台管理系统&#xff0c;我们一般会有查询订单列表页、商品列表页等。 示例&#xff1a; SELECT * FROM goods order by create_time limit 0,10; 在了解order by和limit的工作原理之前&#xff0c…

[DB] (数据库工具) navicat 平替 jookdb

jookdb 官方下载 csdn下载(免积分) 解压后直接可以使用 测试数据库适配性. mysql.mariadb.oracle.sqlserver免费使用 除外的提供20天免费试用驱动添加是java的jdbc驱动,可以通过 https://developer.aliyun.com/mvn/view 进行下载数据库的基本操作.包含数据库的新增, 库表新增…

SQLSERVER 遍历循环的两种方式很详细有源码(1)

1.普通循环 Create table WS_Student ( [Id] int primary key not null, [My_Cocode] [int], [My_SCocode] [int], [userId] [bigint], [SetCName] [varchar](50) NULL, [SetEName] [varchar](50) NULL, [SetPcode] [varchar](50) NULL, [Se…

单相浪涌保护器和三相浪涌保护器的区别

浪涌保护器&#xff0c;也称为防雷器&#xff0c;是一种为各种电子设备、仪器仪表、通讯线路提供安全防护的电子装置&#xff0c;主要用于限制过电压和泄放电涌电流。浪涌保护器的核心元件是内部的一个非线性元件。根据非线性元件的不同&#xff0c;浪涌保护器可以分为开关型&a…

​如何使用ArcGIS Pro制作渐变河流效果

对于面要素的河流水系&#xff0c;制作渐变效果方法比较简单&#xff0c;如果是线要素的河流有办法制作渐变效果吗&#xff0c;答案是肯定的&#xff0c;这里为大家介绍一下制作方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的水系数…

kubernetes部署jenkins

参考&#xff1a; ​​​​​​第七篇&#xff1a;kubernetes部署jenkins-CSDN博客 1、当前kubernetes集群已部署nfs服务 showmount -e 创建jenkins目录 2、添加jenkins的pvc cd /opt/dockerfile/jenkins/ touch jenkins-pv.yaml apiVersion: v1 kind: PersistentVolume m…

软件测试/人工智能丨深入人工智能软件测试:PyTorch引领新时代

在人工智能的浪潮中&#xff0c;软件测试的角色变得愈发关键。本文将介绍在人工智能软件测试中的一些关键技术&#xff0c;以及如何借助PyTorch深度学习框架来推动测试的创新与升级。 PyTorch&#xff1a;深度学习的引擎 PyTorch作为一种开源的深度学习框架&#xff0c;为软件…

【2021集创赛】Arm杯二等奖-基于Arm核的智慧病房手势识别方案

团队介绍 参赛单位&#xff1a;上海交通大学 队伍名称&#xff1a;芯灵手巧 指导老师&#xff1a;王琴、景乃锋 参赛队员&#xff1a;林圣凯、林新源、莫志文 总决赛奖项&#xff1a;二等奖 1.项目概述 1.1 选题背景 我们的选题背景是考虑到很多卧床病人不便于独自向医护人…

.NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试

2023年11月15日&#xff0c;对.net的开发圈是一个重大的日子&#xff0c;.net 8.0正式版发布。 圈内已经预热了有半个月有余&#xff0c;性能不断超越&#xff0c;开发体验越来越完美&#xff0c;早在.net 5.0的时候就各种吹风Aot编译&#xff0c;直到6.0 7.0使用仍然比较麻烦…

比一比国内的现货白银交易所

上海黄金交易所(SGE)是国内最大的白银交易平台之一。它作为中国金融期货市场的重要组成部分&#xff0c;能够提供完善的交易机制和规范的交易环境。SGE的交易品种丰富&#xff0c;包括现货白银&#xff0c;白银延期等的多种交易方式。SGE也具有较高的流动性和交易深度&#xff…

WireGuard 组网教程:快速构建安全高效的私密网络并实现内网穿透

文章目录 1 引言1.1 什么是WireGuard1.2 WireGuard可以用来做什么1.3 WireGuard原理1.4 WireGuard安装 2 WireGuard组网实现内网穿透2.1 前提条件2.2 网络拓扑结构2.3 具体步骤2.3.1 中继服务器配置2.3.2 其他peer2.3.3 测试 2.4 WireGuard配置文件说明 3 WireGuard工具3.1 wg-…

Numpy数组进阶_Python数据分析与可视化

Numpy数组进阶 Numpy的广播机制高级索引整数数组索引布尔索引花式索引 数组迭代 Numpy的广播机制 广播 (Broadcast) 是 numpy 对不同形状 (shape) 的数组&#xff0c;进行数值计算的方式。 对数组的算术运算通常在相应的元素上进行&#xff0c;当运算中的 2 个数组的形状不同时…