Protobuf的设计很是适用于在网络通信中的数据载体,它序列化出来的数据量少再加上以K-V的方式来存储数据,对消息的版本兼容性很是强;还有一个比较大的优势就是有着不少的语言平台支持。下面讲解一下如何在TCP通信应用中集成Protobuf. java
Protobuf提供一种简单的对象消息方式来描述数据的存储,经过相关实现能够简单地实现数据流和对象之间的转换。但因为Protobuf序列化后的信息并不包括一些相应对象类型描述,只有消息体的内容;所以在进行通讯交互过程当中默认状况是不知道这些数据和对象的对应关系;既然对方不清楚这些数据对应那种类型,那数据还源成对象就根本没办法入手。因此把Protobuf用到网络通信中咱们还须要外加一些协议来规范数据的对应关系。 android
在通信协议上只须要在消息体中先写入类型而后再写入Protobuf数据,TypeName主要是用于对方配匹数据对应的对象关系,这个TypeName是string仍是int或其余就根据本身喜爱来制定了。 git
在通信上问题就解决了,但还要面对实际中使用的一种状况消息太多了……那处理TypeName->Object则一个蛋痛的事情。还好在.net和android下有类元素表这玩意还能在运行行进行操做,从而能够大大节省这些if判断处理。因为本人熟悉的语言平台有限,在这里分别提供java和c#的解决方法。 github
public static void Register(Class<?> protobufclass) { try { ProtoMessageHandler mb; Class<?>[] protoObjs = protobufclass.getClasses(); for (Class<?> item : protoObjs) { if(item==null) continue; if (!item.isInterface() && item.getSuperclass().equals( com.google.protobuf.GeneratedMessage.class)) { mb = new ProtoMessageHandler(); mb.SetType(item); mMessageTbl.put(item.getSimpleName(), mb); } } } catch (Exception e) { } }
因为使用Protoc工具生成的类都会生成一个大类里,因此只须要注册指定的类而后对全部继承com.google.protobuf.GeneratedMessage的内嵌类找出来并记录在一个Map中便可。 c#
String name= stream.ReadUTF(); ProtoMessageHandler handler = ProtoPackage.GetMsgHandler(name); if(handler==null) throw new Exception(name+" message type notfound!"); Message=(com.google.protobuf.GeneratedMessage) handler.GetObject(stream.GetStream());
以上是经过类型值获取对应的对象,并填充Protobuf数据。 网络
相对于android平台下的实现,.net的实现就更简单些了。 工具
public static void Register(System.Reflection.Assembly assembly) { foreach(Type type in assembly.GetTypes()) { if (!type.IsAbstract && !type.IsInterface && type.GetCustomAttributes(typeof(ProtoBuf.ProtoContractAttribute), false).Length > 0) mProtoTbl[type.Name] = type; } }
string name = reader.ReadUTF(); Type type = ProtoPakcage.GetProtoType(name); Message = ProtoBuf.Meta.RuntimeTypeModel.Default.Deserialize(reader.Stream, null, type);
经过以上方法在使用Protobuf的时候就不用担忧消息太多写if写到手软了,也不容易出错。不过有一点要注意的就是类的名称必定要对应,不然就没法匹配到消息了。若是想获得彻底整的代码能够到https://beetlenp.codeplex.com获取。 google
我的站:www.ikende.com spa
我的开源项目github.com/IKende
elastic communication component for .net .net