轉(zhuǎn)載自: http://blog.csdn.net/yi_ya/article/details/404042311. 簡(jiǎn)單介紹protobuf文件:就是定義你要的消息(類似java中的類)和消息中的各個(gè)字段及其數(shù)據(jù)類型(類似java類中的成員變量和他的數(shù)據(jù)類型) 2. Protobuf消息定義消息由至少一個(gè)字段組合而成,,類似于C語(yǔ)言中的結(jié)構(gòu)。每個(gè)字段都有一定的格式,。 字段格式:限定修飾符① | 數(shù)據(jù)類型② | 字段名稱③ | = | 字段編碼值④ | [字段默認(rèn)值⑤] 1)限定修飾符包含 required\optional\repeatedRequired: 表示是一個(gè)必須字段,,必須相對(duì)于發(fā)送方,在發(fā)送消息之前必須設(shè)置該字段的值,,對(duì)于接收方,,必須能夠識(shí)別該字段的意思。發(fā)送之前沒有設(shè)置required字段或者無(wú)法識(shí)別required字段都會(huì)引發(fā)編解碼異常,,導(dǎo)致消息被丟棄,。 Optional:表示是一個(gè)可選字段,可選對(duì)于發(fā)送方,,在發(fā)送消息時(shí),,可以有選擇性的設(shè)置或者不設(shè)置該字段的值。對(duì)于接收方,,如果能夠識(shí)別可選字段就進(jìn)行相應(yīng)的處理,,如果無(wú)法識(shí)別,則忽略該字段,,消息中的其它字段正常處理,。---因?yàn)閛ptional字段的特性,很多接口在升級(jí)版本中都把后來(lái)添加的字段都統(tǒng)一的設(shè)置為optional字段,這樣老的版本無(wú)需升級(jí)程序也可以正常的與新的軟件進(jìn)行通信,,只不過新的字段無(wú)法識(shí)別而已,,因?yàn)椴⒉皇敲總€(gè)節(jié)點(diǎn)都需要新的功能,因此可以做到按需升級(jí)和平滑過渡,。 Repeated:表示該字段可以包含[0,N]個(gè)元素,。其特性和optional一樣,但是每一次可以包含多個(gè)值,??梢钥醋魇窃趥鬟f一個(gè)數(shù)組的值。 2)數(shù)據(jù)類型Protobuf定義了一套基本數(shù)據(jù)類型,。幾乎都可以映射到C++\Java等語(yǔ)言的基礎(chǔ)數(shù)據(jù)類型.
N 表示打包的字節(jié)并不是固定。而是根據(jù)數(shù)據(jù)的大小或者長(zhǎng)度,。 例如int32,,如果數(shù)值比較小,在0~127時(shí),,使用一個(gè)字節(jié)打包,。 關(guān)于枚舉的打包方式和uint32相同。 關(guān)于message,,類似于C語(yǔ)言中的結(jié)構(gòu)包含另外一個(gè)結(jié)構(gòu)作為數(shù)據(jù)成員一樣,。 關(guān)于 fixed32 和int32的區(qū)別。fixed32的打包效率比int32的效率高,,但是使用的空間一般比int32多,。因此一個(gè)屬于時(shí)間效率高,一個(gè)屬于空間效率高,。根據(jù)項(xiàng)目的實(shí)際情況,,一般選擇fixed32,如果遇到對(duì)傳輸數(shù)據(jù)量要求比較苛刻的環(huán)境,,可以選擇int32. 3)字段名稱字段名稱的命名與C,、C++、Java等語(yǔ)言的變量命名方式幾乎是相同的,。 protobuf建議字段的命名采用以下劃線分割的駝峰式,。例如 first_name 而不是firstName. 4)字段編碼值有了該值,通信雙方才能互相識(shí)別對(duì)方的字段,。當(dāng)然相同的編碼值,,其限定修飾符和數(shù)據(jù)類型必須相同。 編碼值的取值范圍為 1~2^32(4294967296)。 其中 1~15的編碼時(shí)間和空間效率都是最高的,,編碼值越大,,其編碼的時(shí)間和空間效率就越低(相對(duì)于1-15),當(dāng)然一般情況下相鄰的2個(gè)值編碼效率的是相同的,,除非2個(gè)值恰好實(shí)在4字節(jié),,12字節(jié),20字節(jié)等的臨界區(qū),。比如15和16. 1900~2000編碼值為Google protobuf 系統(tǒng)內(nèi)部保留值,,建議不要在自己的項(xiàng)目中使用。 protobuf 還建議把經(jīng)常要傳遞的值把其字段編碼設(shè)置為1-15之間的值,。 消息中的字段的編碼值無(wú)需連續(xù),,只要是合法的,并且不能在同一個(gè)消息中有字段包含相同的編碼值,。 建議:項(xiàng)目投入運(yùn)營(yíng)以后涉及到版本升級(jí)時(shí)的新增消息字段全部使用optional或者repeated,,盡量不實(shí)用required。如果使用了required,,需要全網(wǎng)統(tǒng)一升級(jí),,如果使用optional或者repeated可以平滑升級(jí),。
5)默認(rèn)值,。當(dāng)在傳遞數(shù)據(jù)時(shí),對(duì)于required數(shù)據(jù)類型,,如果用戶沒有設(shè)置值,,則使用默認(rèn)值傳遞到對(duì)端。當(dāng)接受數(shù)據(jù)是,,對(duì)于optional字段,,如果沒有接收到optional字段,則設(shè)置為默認(rèn)值,。
3. 注意1)關(guān)于importprotobuf 接口文件可以像C語(yǔ)言的h文件一個(gè),,分離為多個(gè),在需要的時(shí)候通過 import導(dǎo)入需要對(duì)文件,。其行為和C語(yǔ)言的#include或者java的import的行為大致相同,。 2)關(guān)于package避免名稱沖突,可以給每個(gè)文件指定一個(gè)package名稱,,對(duì)于java解析為java中的包,。對(duì)于C++則解析為名稱空間。
3)關(guān)于message支持嵌套消息,,消息可以包含另一個(gè)消息作為其字段,。也可以在消息內(nèi)定義一個(gè)新的消息。 關(guān)于enum 枚舉的定義和C++相同,但是有一些限制,。 枚舉值必須大于等于0的整數(shù),。 使用分號(hào)(;)分隔枚舉變量而不是C++語(yǔ)言中的逗號(hào)(,) eg. enum VoipProtocol { H323 = 1; SIP = 2; MGCP = 3; H248 = 4; } |
|
來(lái)自: WindySky > 《protobuf3》