文章介绍
本文主要介绍我学习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语言的形式输出