Protocol Buffers介紹
寫在前面——
如果轉載請註明出處,謝謝大家支持
同步更新51CTO博客
——Forward
我的微博——龍顏碩
基本概念
Protocol Buffers(以下簡稱PB)是一種獨立於語言、獨立於開發平臺、可擴展的序列化數據結構框架,它常常被用在通信、數據序列化保存等方面。
PB是一種敏捷、高效、自動化的用於對數據進行序列化的框架。同XML比較,比XML更小、更快、更簡單。你一旦定義了期望的數據結構,就可以根據定義生成特定的源碼,從而輕而易舉地對你的數據進行讀寫操作,你甚至可以在不修改原來的程序源碼的情況下,更新自己的之前定義的數據結構。
PB與其他協議的比較
語言:
PB與Json都是跨語言的,PB支持C++、Java、Python等語言;
Json支持的語言比PB更多,類似Json結構;
XML結構支持的語言也是要比PB更多。
結構:
PB發送與接受的數據屬於一個完整的對象;
Json發送與接受的是一個鍵值對的數據結構;
XML結構從本質上講也是一種鍵值對的數據結構。
數據保存:
PB是二進制方式方式保存;
Json屬於文本保存;
XML保存的是文本
(說明:文本的話更容易被破解,如果要在網絡傳輸中使用,後面兩種我們就得自己去實現加密算法來保證數據在網絡中的安全性了,當然,並不是說PB的二進制就完全沒法破解,只是較之其他兩種結構來說安全一點)。
開發和擴展成本:
PB只要維護一份proto文件就可以直接生成特定語言的類,保證了開發的高效,降低了維護成本;
Json協議一般需要發送與接受方事先定義好結構,同時因爲Json協議解析的時候是大小寫敏感的,使得開發和維護成本較之PB略高;
XML結構一般來說組織和解析都是需要開發人員自己去實現,開發成本和維護成本比PB和Json更高;
適用範圍:
PB和Json一般大都使用在客戶端與服務器通信模塊,主要是因爲數據的組織和解析較爲簡單;
而XML結構一般是作爲配置文件來使用,主要是因爲方便屬性的配置和修改。
通過下面的表格我們可以更清楚這三種結構之間的關係:
協議 | 語言 | 結構 | 數據保存 | 開發成本 | 數據大小 | 適用範圍 |
PB | C++/Java/Python | 對象 | 二進制文件 | 低 | 小 | C/S通信 |
Json | 多種 | 鍵值對 | 文本 | 較低 | 一般 | C/S通信 |
XML | 多種 | 鍵值對 | 文本 | 高 | 大 | 配置文件 |
表1
PB的使用過程
1、定義自己的數據結構
PB允許我們定義自己期望的數據結構Message,它的定義是通過.proto文件來實現的。每個Message都是一個信息的邏輯記錄塊,這個塊包括了一系列鍵對值(“鍵”相當於生成對應類文件的屬性名,“值”表示這個屬性的權限)
這裏是作者自己寫的一個.proto文件。
圖1
如圖1前兩行分別定義了java包名和類名,在這個結構中,作者定義了一個WorkerInfoList,這就相當於一個員工的信息列表,每個員工信息定義在Work中,其中包括了員工號(id)、員工姓名(name)、員工郵箱(email)、員工地址(address)等信息。這樣我們就完成了一個PB的模板(.proto文件)。
這裏需要說明的是模板定義中使用的三種不同的屬性optional、required以及repeated。
Optional屬性說明該屬性是可選的,就是說在組織數據包時,這個數據項可以是可有可無的。
Required屬性說明該屬性是必須有值的,不可爲空。
Repeated屬性說明該屬性是一個列表,我們可以把這種數據項理解爲一個list來使用。
2、生成對應語言的源碼;
有了模板這是第一步,接下來就要通過這個模板去生成對應語言下的類文件,google爲我們提供了生成工具(protoc.exe,很多地方都可以下載到),作者是從https://developers.google.com/protocol-buffers/這裏下載了(作者在使用的時候,ProtocolBuf最新版本是2.4.1)。
下載完成打開之後我們可以看到如下圖2的目錄結構:
圖2
其中protoc工程編譯之後就可以得到我們需要的protoc.exe工具。
在cmd中啓動protoc並給定參數就可以生成我們需要的C、Java、Python的類文件。這裏,作者簡單對protoc生成對應文件的參數做一說明:
--proto_path參數是指定我們的proto模板的目錄(不要定義成這個模板文件,否則會報“Not find file”的錯誤);
第二個參數取決於我們想生成的文件類型,如果想生成C++的類參數名是“—cpp_out”;如果想生成Java的類參數名是“—java_out”;同理,如果想生成Python類,參數名就是“—python_out”。
接下來我們通過上面定義的模板來生成對應的類文件:
C++:
圖3
Java:
圖4
Python:
圖5
生成結果如下所示:
C++類文件:
圖6
Java類文件:
圖7
Python類文件:
圖8
這裏需要單獨說明一下的是Java類文件生成的時候會出現多級目錄,這個前面已經說過,每一層的目錄是我們在模板中定義的。
3、使用
有了類文件,我們就可以通過對應的API去組織和解析對應的數據了。這裏簡單說一下C++中的類調用(Java和Python中的使用可以自己去查看)。
圖9
如圖9是上面的模板中Worker類的id調用接口。id返回數據值,set_id設置數據值這些接口基本都可以通過名字知道其含義。
圖10
圖10中,是WorkInfoList的接口,因爲這個類中包含了一個Worker的repeated數據項,前面說過我們可以把它當做一個list來使用,即在組織數據的時候通過add_workerinfo來添加一項員工數據,這個接口返回其指針,通過mutable_workerinfo(int index)接口來獲取下標爲index的數據指針並進行操作(設置數據等);在解析其參數的時候通過workinfo(int index)來獲取下標爲index的數據等等。具體的我們可以在真正使用的時候去進一步熟悉掌握。