【Unity3D】在Unity中使用Protobuf(proto3)

有研究表明,一條消息數據,用protobuf序列化後的大小是json的10分之一,xml格式的20分之一,是二進制序列化的10分之一,ProtoBuf的優勢還是很明顯的。這裏簡單介紹哈使用

 

一、下載protobuf

https://github.com/google/protobuf/releases

選擇protoc-3.6.0-win32.zip下載

 

二、編寫proto原文件

syntax = "proto3";//標明proto版本

package protobuf;//包名

//一個message相當於一個類
//1,2,3不代表參數默認值,而是參數標籤
//repeated 可以理解爲數組

message StoreRequest {
  string name = 1;
  int32 num = 2;
  int32 result = 3;
  repeated string myList=4;
}

(1)版本號

對於一個pb文件而言,文件首個非空、非註釋的行必須註明pb的版本,即syntax = "proto3";,否則默認版本是proto2。

(2)Message

一個message類型看上去很像一個Java class,由多個字段組成。每一個字段都由類型、名稱組成,位於等號右邊的值不是字段默認值,而是數字標籤,可以理解爲字段身份的標識符,類似於數據庫中的主鍵,不可重複,標識符用於在編譯後的二進制消息格式中對字段進行識別,一旦你的pb消息投入使用,字段的標識就不應該再改變。數字標籤的範圍是[1, 536870911],其中19000~19999是保留數字。

(3)類型

每個字段的類型(int32,string)都是scalar的類型,和其他語言類型的對比如下:

(4)修飾符

如果一個字段被repeated修飾,則表示它 是一個列表類型的字段,比如上面

 repeated string myList=3; 

等於是List<string> myList

如果你希望可以預留一些數字標籤或者字段可以使用reserved修飾符:

message Login {
  reserved 2, 15, 9 to 11;
  reserved "lg", "bo";
  string bo = 3; // 編譯報錯,因爲‘bo’已經被標爲保留字段
}

(5)默認值

  1. string類型的默認值是空字符串
  2. bytes類型的默認值是空字節
  3. bool類型的默認值是false
  4. 數字類型的默認值是0
  5. enum類型的默認值是第一個定義的枚舉值
  6. message類型(對象,如上文的SearchRequest就是message類型)的默認值與語言相關
  7. repeated修飾的字段默認值是空列表

注:如果一個字段的值等於默認值(如bool類型的字段設爲false),那麼它將不會被序列化,這樣的設計是爲了節省流量

 

(6)枚舉

每個枚舉值有對應的數值,數值不一定是連續的。第一個枚舉值的數值必須是0且至少有一個枚舉值,否則編譯報錯。編譯後編譯器會爲你生成對應語言的枚舉類。

 

message StoreRequest {
  string name = 1;
  int32 number = 2;
  int32 result = 3;
enum CoinType
{
    None=0;
    CT_cny = 1;
    CT_usd = 2;
    CT_hkd = 3;
    CT_jpy = 4;
    CT_eur = 5;
}
  CoinType coin = 4;
}

可以使用MessageType.EnumType的形式引用定義在其它message類型中的枚舉。

 

注:由於編碼原因,出於效率考慮,官方不推薦使用負數作爲枚舉值的數值。

 

(7)Maps

pb中也可以使用map類型(官方並不認爲是一種類型,此處稱之爲類型僅便於理解),絕大多數scalar類型都可以作爲key,除了浮點型和bytes,枚舉型也不能作爲key,value可以是除了map以外的任意類型:

map<string, object> obj = 3;

map其實是一種語法糖,它等價於以下形式:

message MapField {
  key_type key = 1;
  value_type value = 2;
}

repeated MapField map_field = N;

注:map類型字段不支持repeated,value的順序是不定的。

 

(8)包

你可以用指定package以避免類型命名衝突:

package store.ba;
message Buy{...}

然後可以用類型的全限定名來引用它:

message Store{
...
store.ba.Buy buy=1;
..
}

指定包名後,會對生成的代碼產生影響,生成的類會以你指定的package作爲包名。

這裏不再做詳細介紹,可以參照https://developers.google.com/protocol-buffers/docs/encoding?hl=zh-cn

 

 

三、配置環境變量

將解壓出來的protoc.exe放在一全英文路徑下,並把其路徑名放在windows環境變量下的path下。

(1)以win7爲例,右鍵我的電腦->屬性->高級系統設置->環境變量->系統變量->雙擊修改 變量”path” ,添加protoc.exe的路徑,即:

;E:\protoc-3.6.0-win32\bin

 

(2)打開cmd 執行

protoc --version

顯示libprotoc  3.6.0即配置完畢

 

四、win+R打開cmd窗口執行以下命令

E:\protoc-3.6.0-win32\bin\protoc.exe -I=e:\protoc-3.6.0-win32\bin   --csharp_out=e:\protoc-3.6.0-win32\bin    e:\protoc-3.6.0-win32\bin\msg.proto
 

若配置了環境變量:

protoc -I=e:\protoc-3.6.0-win32\bin     --csharp_out=e:\protoc-3.6.0-win32\bin     e:\protoc-3.6.0-win32\bin\msg.proto
 

protoc -I=源地址     --csharp_out=目標地址      源地址/xxx.proto

 

五、然後就看到目標路徑生成了Msg.cs

(未完待續)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章