protocol buffer開發指南

ProtoBuf 是一套接口描述語言(IDL)和相關工具集(主要是 protoc,基於 C++ 實現),相似 Apache 的 Thrift)。用戶寫好 .proto 描述文件,以後使用 protoc 能夠很容易編譯成衆多計算機語言(C++、Java、Python、C#、Golang 等)的接口代碼。(摘自:ProtoBuf 與 gRPC 你須要知道的知識git

注:本文參考Protocol Buffers 3.0 技術手冊,下面給出該文章中未說明的部分github

 

定義Message類型apache

1 syntax = "proto3";
2 
3 message SearchRequest {
4   string query = 1;
5   int32 page_number = 2;
6   int32 result_per_page = 3;
7 }

 

  首行指定了使用proto3語法,若是沒有改行,protocol buffer編譯器默認使用proto2。安全

  field numbersapp

  4,5,6行中指定了field number,field number的取值範圍爲1~(229-1)。protocol buffer的預留了19000~19999(FieldDescriptor::kFirstReservedNumber ~ FieldDescriptor::kLastReservedNumber)之間的值。
ide

  field rules工具

消息字段有2種規則:大數據

  • singular:0或1個,但不能多於1個
  • repeated:任意數目 

  defaultui

  當解析 message 時,若是被編碼的 message 裏沒有包含特定變量,根據類型不一樣,他們會有不一樣的默認值:google

  • string:默認是空的字符串
  • byte:默認是空的bytes
  • bool:默認爲false
  • numeric:默認爲0
  • enums:定義在第一位的枚舉值,也就是0
  • messages:根據生成的不一樣語言有不一樣的表現,參考generated code guide

注意:對於scalar(標準protobuf類型,如) message字段,一但message被解析,則沒有辦法來明確判斷該字段設置了默認值(如無法判斷一個boolean變量設置爲false)或根本沒有設置。所以在定義message類型的時候必定要注意,例如,若是不想在默認下有任何動做,則boolean的值在false時不要有動做。此外注意,scalar message字段在設置爲默認值時,該值不會被序列化--->即反序列化scalar message字段時是沒法反序列化出默認值(由於默認值不會被序列化)

  • 不要修改任何已存在的變量的 Tag
  • 若是你新增了變量,新生成的代碼依然能解析舊的數據,但新增的變量將會變成默認值。相應的,新代碼序列化的數據也能被舊的代碼解析,但舊代碼會自動忽略新增的變量。
  • 廢棄不用的變量使用兩個OBSOLETE_"前綴或用 reserved 標註
  • int3二、 uint3二、 int6四、 uint64 和 bool 是相互兼容的,這意味你能夠更改這些變量的類型而不會影響兼容性
  • sint32 和 sint64 是兼容的,但跟其餘類型不兼容
  • string 和 bytes 能夠兼容,前提是他們都是UTF-8編碼的數據
  • fixed32 和 sfixed32 是兼容的, fixed64 和 sfixed64是兼容的
  • enum和int32,int64,uint32,uint64是兼容的(注意:若是類型不一致可能會被截斷)。須要注意的是,客戶端解碼message時可能會給出不一樣的解釋,如未識別的proto3 enum類型會保存在message中,但如何解釋則依賴於解碼的語言。
  • 改變一個新加的oneof成員值是安全且二進制兼容的;爲現有的oneof添加字段則不安全。

未識別的字段

  未識別的字段爲序列數據中出現的沒法解析的字段,如當老的二進制解析器解析一個包含新字段的二進制時,新字段即爲沒法識別的字段。

  proto3能夠很好地解析未識別的字段,然而proto實現時可能會也可能不會保留這些未知的字段,功能實現不該該依賴於未知字段是否保留或丟棄。

oneof

  oneof相似C語言的聯合體union,oneof中不能使用repeated

option

  全部有效的選項都定義在google/protobuf/descriptor.proto,參見option

 

使用場景 

多消息流

  若是向一個文件或流中寫入多個消息,則須要本身去跟蹤一個消息的結束和下一個消息的開始。因爲protocol buffers不會對自限定長度,解析器沒法斷定消息的結束點,簡單的方式是在寫入消息前先寫入消息的長度。

大數據集

  protocol buffer並非設計用來處理大消息的,若是有大規格的消息,能夠分割解決。

參考:Language Guide (proto3)

相關文章
相關標籤/搜索