GRPC之protobuf理解

ice_moss發表於2022-05-18

文章介紹

本文主要介紹我學習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語言的形式輸出

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章