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);