GRPC之protobuf理解

Golang
555
0
0
2022-10-17
标签   gRPC

文章介绍

本文主要介绍我学习protobuf的理解和总结、主要介绍protobuf的基本类型、option的作用、proto文件中导入其他proto文件、嵌套message、enum枚举类型、map类型、proto中内置的timetram类型及service{}

protobuf介绍

protobuf全称Google Protocol Buffers,是google开发的的一套用于数据存储,网络通信时用于协议编解码的工具库。protobuf是一种灵活高效的独立于语言平台的结构化数据表示方法。在通信协议和数据存储等领域中使用比较多。protobuf对于结构中的每个成员会提供set系列函数和get系列函数。与XML相比,protoBuf更小更快更简单。你可以用定义protobuf的数据结构。用protobuf编译器生成特定语言的源代码,如C++,Java,go,Python等,proto文件是以xxx.proto命名的。

基本类型

int

int32
int64
  • float
float
  • string
string
  • 这是常用的基本类似,更多类型请参考官方地址

option的作用

我们先来看一个简单的proto文件

syntax = "proto3";  //值proto3的语法

option go_package="/.;proto";  

option:指生成的哪一个语言的代码及生成目的文件下

go_package:指生成go语言的代码

"/.;proto":指在当前文件下生成,并且包名为proto

proto文件中导入其他proto文件

我们在开发的过程中,难免会遇到代码重复使用的情况,这时我们可以将proto文件导入

例如:我们要使用case.prot的内容,我们就需要导入case.proto文件,则使用import

syntax = "proto3";
option go_package="/.;proto";
import "case.proto";  //

然后我们就可以使用case.proto中的内容了

  • case.proto:
syntax = "proto3";
option go_package = "/.;proto";

message IsEmpty{}

message Pong{
    string id = 1;
}
  • holle.proto:
syntax = "proto3";

option go_package="/.;proto";
//引入protobuf的内置类型
import "google/protobuf/timestamp.proto";
import "case.proto";

//定义接口
service Greeter {
    rpc SayHello (HolleRequest) returns (HolleReply);
    rpc Ping(IsEmpty) returns (Pong);     //Ping(IsEmpty) returns (Pong)中的IsEmpty,Pong来自case.proto中
}

message HolleRequest {
    string name = 1;
    string url = 2;
}

message HolleReply {
    string id = 1;
}

message及嵌套message

message

我们还是直接看代码:

message HolleRequest {
    string name = 1;  //name = 1不是赋值,是指在字段的编号 
    string url = 2;
}

这就是一个简单的message他类似于结构体,message内部我们可以定义他的字段,这里需要注意的是:

string name = 1;
string url = 2;

不是赋值,而是给字段的编号

嵌套message
  • 我们可以在message嵌套一个或者多个message, 下面我们来看示例:
message HolleRequest {
    string name = 1;
    string url = 2;
}

message HolleReply {
    string id = 1;
    HelloRequest request = 2;   //HelloReply中嵌套HelloRequest
}
  • 这样我们就实现了message的嵌套

enum枚举类型

enum枚举类型是我们在业务中经常需要使用的,例如,性别(男,女)、用户身份认证(为认证,认证中,认证失败)等,这里我们以性别为例:

//枚举类型
enum Gender{
    MALE = 0;
    FE_MALE = 1;
}

一个简单的枚举类型就定义完成了,那么可以把他放入我们的message中:

message HolleRequest {
    string name = 1;
    string url = 2;
    Gender gender = 3;
}

map类型

我们只需要map<string, string> mp = 4;

message HolleRequest {
    string name = 1;
    string url = 2;
    Gender gender = 3;
    map<string, string> mp = 4;  //proto map类型
}

timestamp内置类型

proto中也有一些内置的类型,例如我们要介绍的timestamp

我们使用它时,需要导入 “google/protobuf/timestamp.proto”这个是protobuf官方定义的

message HolleRequest {
    string name = 1;
    string url = 2;
    Gender gender = 3;
    map<string, string> m = 4;  //proto map类型
    google.protobuf.Timestamp addTime = 5;  //protobuf的内置类型
}

service{}

这里我的理解是我们上面介绍的所有类型最后都是为了service{}而准备的,service{}我们可以理解是一个接口,里面有我们定义的各种方法,最后我们在业务中调用的方法也来自于此。

service Greeter {
        //定义了一个SayHello方法,入参:HolleRequest, 出参:HelloReply
    rpc SayHello (HolleRequest) returns (HelloReply); 
}

假如我们有一个业务需要:我们需要给用户信息绑定一个id,以便于业务在后期快速查找

我们这样定义proto文件:

syntax = "proto3";

option go_package="/.;proto";
//引入protobuf的内置类型
import "google/protobuf/timestamp.proto";


//定义接口
service Greeter {
    rpc SayHello (HolleRequest) returns (HelloReply);
}

//枚举类型
enum Gender{
    MALE = 0;
    FE_MALE = 1;
}

message HolleRequest {
    string name = 1;
    string url = 2;
    Gender gender = 3;
    map<string, string> m = 4;  //proto map类型
    google.protobuf.Timestamp addTime = 5;  //protobuf的内置类型
}

message HelloReply {
    string id = 1;
    HolleRequest request = 2;
}

这样我们的proto文件就完成了,那如何使用它生成对应语言的业务代码呢?

我们使用命令:

protoc -I . holle.proto --go_out=plugins=grpc:. 

-I:表示输入input 即输入文件

.:表示在当前目录,这里也可以使用绝对路径或者相对路径

holle.proto:就是我们写的proto文件

--go_out:输出,以go语言的形式输出