Protobuf 協議語言指南
l 定義一個訊息(message)型別
l 標量值型別
l Optional 的欄位及預設值
l 列舉
l 使用其他訊息型別
l 巢狀型別
l 更新一個訊息型別
l 擴充套件
l 包(package)
l 定義服務(service)
l 選項(option)
l 生成訪問類
本指南描述了怎樣使用protocolbuffer語言來構造你的protocol buffer資料,包括.proto檔案語法以及怎樣生成.proto檔案的資料訪問類。
本文是一個參考指南——如果要檢視如何使用本文中描述的多個特性的循序漸進的例子,請在http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/tutorials.html中查詢需要的語言的教程。
l 定義一個訊息型別
先來看一個非常簡單的例子。假設你想定義一個“搜尋請求”的訊息格式,每一個請求含有一個查詢字串、你感興趣的查詢結果所在的頁數,以及每一頁多少條查詢結果。可以採用如下的方式來定義訊息型別的.proto檔案了:
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
}
SearchRequest訊息格式有3個欄位,在訊息中承載的資料分別對應於每一個欄位。其中每個欄位都有一個名字和一種型別。
Ø 指定欄位型別
在上面的例子中,所有欄位都是標量型別:兩個整型(page_number和result_per_page),一個string型別(query)。當然,你也可以為欄位指定其他的合成型別,包括列舉(enumerations)或其他訊息型別。
Ø 分配標識號
正如上述檔案格式,在訊息定義中,每個欄位都有唯一的一個識別符號。這些識別符號是用來在訊息的二進位制格式中識別各個欄位的,一旦開始使用就不能夠再改變。注:[1,15]之內的標識號在編碼的時候會佔用一個位元組。[16,2047]之內的標識號則佔用2個位元組。所以應該為那些頻繁出現的訊息元素保留[1,15]之內的標識號。切記:要為將來有可能新增的、頻繁出現的標識號預留一些標識號。
最小的標識號可以從1開始,最大到229 - 1, or 536,870,911。不可以使用其中的[19000-19999]的標識號, Protobuf協議實現中對這些進行了預留。如果非要在.proto檔案中使用這些預留標識號,編譯時就會報警。
Ø 指定欄位規則
所指定的訊息欄位修飾符必須是如下之一:
² required:一個格式良好的訊息一定要含有1個這種欄位。表示該值是必須要設定的;
² optional:訊息格式中該欄位可以有0個或1個值(不超過1個)。
² repeated:在一個格式良好的訊息中,這種欄位可以重複任意多次(包括0次)。重複的值的順序會被保留。表示該值可以重複,相當於java中的List。
由於一些歷史原因,基本數值型別的repeated的欄位並沒有被儘可能地高效編碼。在新的程式碼中,使用者應該使用特殊選項[packed=true]來保證更高效的編碼。如:
repeated int32 samples = 4 [packed=true];
required是永久性的:在將一個欄位標識為required的時候,應該特別小心。如果在某些情況下不想寫入或者傳送一個required的欄位,將原始該欄位修飾符更改為optional可能會遇到問題——舊版本的使用者會認為不含該欄位的訊息是不完整的,從而可能會無目的的拒絕解析。在這種情況下,你應該考慮編寫特別針對於應用程式的、自定義的訊息校驗函式。Google的一些工程師得出了一個結論:使用required弊多於利;他們更願意使用optional和repeated而不是required。當然,這個觀點並不具有普遍性。
Ø 新增更多訊息型別
在一個.proto檔案中可以定義多個訊息型別。在定義多個相關的訊息的時候,這一點特別有用——例如,如果想定義與SearchResponse訊息型別對應的回覆訊息格式的話,你可以將它新增到相同的.proto檔案中,如:
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
}
message SearchResponse {
…
}
Ø 添加註釋
向.proto檔案添加註釋,可以使用C/C++/java風格的雙斜槓(//) 語法格式,如:
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;// 最終返回的頁數
optional int32 result_per_page = 3;// 每頁返回的結果數
}
Ø 從.proto檔案生成了什麼?
當用protocolbuffer編譯器來執行.proto檔案時,編譯器將生成所選擇語言的程式碼,這些程式碼可以操作在.proto檔案中定義的訊息型別,包括獲取、設定欄位值,將訊息序列化到一個輸出流中,以及從一個輸入流中解析訊息。
² 對C++來說,編譯器會為每個.proto檔案生成一個.h檔案和一個.cc檔案,.proto檔案中的每一個訊息有一個對應的類。
² 對Java來說,編譯器為每一個訊息型別生成了一個.java檔案,以及一個特殊的Builder類(該類是用來建立訊息類介面的)。
² 對Python來說,有點不太一樣——Python編譯器為.proto檔案中的每個訊息型別生成一個含有靜態描述符的模組,,該模組與一個元類(metaclass)在執行時(runtime)被用來建立所需的Python資料訪問類。
你可以從如下的文件連結中獲取每種語言更多API。http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/reference/overview.html
---------------------
作者:zhaozheng7758
來源:CSDN
原文:https://blog.csdn.net/zhaozheng7758/article/details/6749047
版權宣告:本文為博主原創文章,轉載請附上博文連結!