歡迎閱讀我的開源項目《迷你微信》服務器與《迷你微信》客戶端
使用原因protocolbuffer(以下簡稱Protobuf)是google 的一種數據交換的格式,它獨立于語言,獨立于平臺。google 提供了三種語言的實現:java、c++ 和 python,每一種實現都包含了相應語言的編譯器以及庫文件。由于它是一種二進制的格式,比使用 xml 進行數據交換快許多。可以把它用于分布式應用之間的數據通信或者異構環境下的數據交換。作為一種效率和兼容性都很優秀的二進制數據傳輸格式,可以用于諸如網絡傳輸、配置文件、數據存儲等諸多領域。——維基百科
在不同語言的前后端交互時,由于不能直接調用,所以必須有一套相同的讀寫協議來規定數據的格式,也就是說,在服務器與客戶端交互時,將要傳輸的內容按照規定模式轉化為一種中間語言(byte數組),然后在另一端根據同樣的格式轉換回自己語言的對象,在這個過程中,可能會出現一些問題,如:
而Protobuf的出現,解決了這樣一種隱患。首先Protobuf是用一種獨立的Protob語言寫的,簡單易懂,并且從這一層直接去除掉語法錯誤問題;接著,Protobuff可以通過需要編譯成不同的語言,從這一層解決了雙方不一致和變更時衍生的問題。
定義Protobuf在這里咱們簡單的介紹一下Protobuf的幾個常用語法:
package protocol;import "Member.proto";option java_package = "protocol.Data";message UserItem{enum Sex{MALE = 0;FEMALE = 1;}required string userName = 1;required Sex sex = 2;optional int32 father = 3;repeated PersonalInfo personalInfo = 4;}咱們來解釋一下這里面的代碼分別是什么意思:
import "Member.proto";表示導入另一個Protobuf,這樣就可以使用里面定義的message 對象PersonalInfo 了。
option java_package = "protocol.Data";表示將這個寫好的Protobuf文件在編譯時編譯如protocol/Data文件夾下。
message UserItem表示對象的名稱,比如編譯成Java文件后,就是叫做UserItem.java的文件。
enum Sex是一個枚舉的使用,下面就用到了這個Sex。
required string userName = 1;表示UserItem這個對象中有一個叫userName的參數,參數類型是String,requested表示在使用時,這個參數必須被填入,否則將報錯!
optional與requested使用方式類似,表示在使用中這個參數可填可不填。
repeated PersonalInfo personalInfo = 4中的repeated則表示這個參數可能有多個(可以沒有),PersonalInfo類型來自import "Member.proto";。
注意:.proto文件不能與定義的對象名(在這里是UserItem)相同,否則會編譯失敗!帖主就在此栽過跟頭。o(>﹏<)o
使用這里只介紹Java中對于Protobuf的使用(可參考《迷你微信》服務器),想了解C#對Protobuf的使用,請參考《迷你微信》客戶端。
開始想要在Java中使用Protobuf,首先要定義好Protobuf,然后用控制臺指令進行編譯,控制臺在.proto文件的地址下,輸入protoc --java_out=./ ./(我的proto文件名).proto
運行成功后,會在制定目錄下出現(我的proto文件名).java文件,將其復制到你的Java項目中就可以使用了。
當你要將你的數據轉化為Protobuf對象時,需要這樣創建:
import UserItemMsg;..........// 創建UserItemMsg.UserItem.Builder builder = UserItemMsg.UserItem.newBuilder();// 設置數值builder.setUserName = "楓露霜陽";builder.setSex(UserItemMsg.UserItem.Sex.MALE);builder.addPhone = "18252060997";builder.addPhone = "110";// 要build起來UserItemMsg uim = builder.build();// 若是要轉成byte數組byte[] byteArray = uim.toByteArray();上述代碼將Protobuf在java中的類創建、設值、build、轉為byte數組,最后用于網絡傳輸。
反解上面將Protobuf的Java類轉化為byte數組,然后通過網絡傳輸,到了接收端,如何將其解回Java對象呢?
import UserItemMsg;...............// 得到傳過來的byte數組byte[] byteArray = fromClientByteArray;UserItemMsg.UserItem userItem = UserItemMsg.UserItem.parseFrom(byteArray);// 獲取數值String userName = userItem.getUserName();后話至此,我們就把Protobuf的簡單使用描述了一遍,若想看看帖主項目的詳細使用請戳下面傳送門。
歡迎閱讀我的開源項目《迷你微信》服務器與《迷你微信》客戶端
新聞熱點
疑難解答