protocol buf
簡介
是一個高效的,跨語言的二進制傳輸語言
google 推出的
后續的消息增加也不會改變原來的消息結構,只需后續增加即可
使用概要
下載protocol 編譯器,jar包
編寫Message消息類型
導出的java文件命令,使用該命令直接生成java代碼protoc.exe --java_out=. Account.proto//Account.proto是消息的名字
參數說明
package com.wang.demo; //打的包option java_package = "com.wang.demo"; //包名
option java_outer_classname = "AccountEntity";//類名
message Account { //消息的名字Account
required int32 id = 1; //required 必選 option 可選 repeat 可以重復的 數字表示參數的排序隨意把
required string account = 2 [default = 0]; // default 默認值
required string password = 3;
optional string nickname = 4;
required string sex = 5;
optional int32 status = 6 [default = 0];
}
對於參數來說required 是必須的參數,在后續的改變中是不能申明為optional,出錯,google工程師 推薦使用optional
拓展
允許在一個文件中寫多個消息
message類型的消息是允許多層拓展的
message類型是允許使用枚舉類型eg:
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3 [default = 10];
enum Corpus { //枚舉類型使用enum關鍵字
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
optional Corpus corpus = 4 [default = UNIVERSAL];
}
類型的說明.proto類型 Java 類型 C++ 類型 備注
double double double
float float float
int32 int int32 使用可變長編碼方式。編碼負數時不夠高效——如果你的字段可能含有負數,那么請使用sint32。
int64 long int64 使用可變長編碼方式。編碼負數時不夠高效——如果你的字段可能含有負數,那么請使用sint64。
uint32 int[1] uint32 Uses variable-length encoding.
uint64 long[1] uint64 Uses variable-length encoding.
sint32 int int32 使用可變長編碼方式。有符號的整型值。編碼時比通常的int32高效。
sint64 long int64 使用可變長編碼方式。有符號的整型值。編碼時比通常的int64高效。
fixed32 int[1] uint32 總是4個字節。如果數值總是比總是比228大的話,這個類型會比uint32高效。
fixed64 long[1] uint64 總是8個字節。如果數值總是比總是比256大的話,這個類型會比uint64高效。
sfixed32 int int32 總是4個字節。
sfixed64 long int64 總是8個字節。
bool boolean bool
string String string 一個字符串必須是UTF-8編碼或者7-bit ASCII編碼的文本。
bytes ByteString string 可能包含任意順序的字節數據。
編譯速度方面的拓展option optimize_for = CODE_SIZE;
optimize_for (fileoption): 可以被設置為 SPEED, CODE_SIZE,or LITE_RUNTIME。這些值將通過如下的方式影響C++及java代碼的生成:
SPEED (default): protocol buffer編譯器將通過在消息類型上執行序列化、語法分析及其他通用的操作。這種代碼是最優的。
CODE_SIZE: protocol buffer編譯器將會產生最少量的類,通過共享或基於反射的代碼來實現序列化、語法分析及各種其它操作。采用該方式產生的代碼將比SPEED要少得多, 但是操作要相對慢些。當然實現的類及其對外的API與SPEED模式都是一樣的。這種方式經常用在一些包含大量的.proto文件而且並不盲目追求速度的 應用中。
LITE_RUNTIME: protocol buffer編譯器依賴於運行時核心類庫來生成代碼(即采用libprotobuf-lite 替代libprotobuf)。這種核心類庫由於忽略了一 些描述符及反射,要比全類庫小得多。這種模式經常在移動手機平台應用多一些。編譯器采用該模式產生的方法實現與SPEED模式不相上下,產生的類通過實現 MessageLite接口,但它僅僅是Messager接口的一個子集。
在java代碼中實際運用
解析msg的消息類型eg:
StoryBothMsgProto.StoryAndAlbumInfoMsg storyAndAlbumInfoMsg=StoryBothMsgProto.StoryAndAlbumInfoMsg.parseFrom(body);//google的自動生成的代碼
StoryBothMsgProto.StoryInfoMsg storyInfoMsg = storyAndAlbumInfoMsg.getStoryInfoMsg();//自動生成的
StoryBothMsgProto.StoryAlbumInfoMsg storyAlbumInfoMsg = storyAndAlbumInfoMsg.getStoryAlbumInfoMsg();
StoryChapter storyChapter = new StoryChapter();//另外的一個bean
storyChapter.setTitle(storyInfoMsg.getTitle());//得到具體的屬性,其實也是很簡單的
storyChapter.setDuration(storyInfoMsg.getDuration());//直接獲取了里面的屬性
String url = storyAlbumInfoMsg.getCoverUrl();
url = url.substring(url.indexOf("http"), url.length());
storyChapter.setCoverUrl(url);
storyChapter.setAnnoumcerName(storyInfoMsg.getAuthor());
storyChapter.setFileSize(storyInfoMsg.getSize());
storyChapter.setId(storyInfoMsg.getId());
storyChapter.setOrderNum(storyInfoMsg.getOrderNum());
生成msg的消息類型eg:
MiscAC2SMsgProto.LoginForAppCMsg.Builder builder = MiscAC2SMsgProto.LoginForAppCMsg.newBuilder();//這是創建消息類型,感覺萌萌噠
builder.setToken(token); // builder 模式創建
MiscAC2SMsgProto.LoginForAppCMsg info = builder.build();
//TCP 的socket 發消息
byte[] result = info.toByteArray();
Short code = KeysTCPStateCode.KEY_STATE_LOGIN_REQUEST;
byte type = KeysTCPStateCode.MESSAGE_TYPE;
com.gowild.xsocket.Message msg = com.gowild.xsocket.Message.createMessage(type, code);
msg.setBody(result);
getConnection().sendMessage(msg);