大家都说google protobuf很好用,这两天有时间研究了一下,果然很满意;
才开始研究的时候,始终在想一个问题:protobuf里面没有消息头,包长度,如果我有多个消息类型的话,发送方还好说,但是到了接收方,该如何识别接收到的是哪个消息类型呢?苦苦思考良久,发现其实是我的思路原本就不对,其实在发送的时候,把消息头和消息体不要放在一个message里,分开序列化就ok了,费话就不多说了,测试代码如下:
OPlayVideoMsg playVideMsg = OPlayVideoMsg.newBuilder().setPlayurl("http://111.3pg").setPlayspeed(1).build();
byte[] bodybytes = playVideMsg.toByteArray();
OMsgHead head = OMsgHead.newBuilder().setMsgtype(1).setMsglen(bodybytes.length).setMsgseq(2).build();
byte[] headerbytes = head.toByteArray();
ByteArrayOutputStream bos = null;
DataOutputStream dos = null;
try {
bos = new ByteArrayOutputStream();
dos = new DataOutputStream(bos);
dos.writeInt(headerbytes.length);
dos.write(headerbytes);
dos.write(playVideMsg.toByteArray());
// 解析罗
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = null;
DataInputStream dis = null;
byte[] headbytes;
try {
bis = new ByteArrayInputStream(bytes);
dis = new DataInputStream(bis);
int headSize = dis.readInt();
System.out.println(String.format("headSize=%d", headSize));
headbytes = new byte[headSize];
dis.read(headbytes);
OMsgHead header = OMsgHead.parseFrom(headbytes);
System.out.println("header======>" + header);
byte[] parsebodybytes = new byte[header.getMsglen()];
dis.readFully(parsebodybytes);
if (header.getMsgtype() == 1) {
OPlayVideoMsg playVideoMsg = OPlayVideoMsg.parseFrom(parsebodybytes);
System.out.println("OPlayVideoMsg======>" + playVideoMsg);
}
} finally {
if (dis != null)
dis.close();
if (bis != null)
bis.close();
}
} finally {
if (dos != null)
dos.close();
if (bos != null)
bos.close();
}
看到35行没,只要解析出头来,就可以继续序列化相应的消息体。
附上我的proto文件:package msginfo;
option java_package = "com.example.tutorial";
message OMsgHead
{
required int32 msgtype = 1;
required int32 msgseq = 2;
required int32 msglen = 3;
}
message OPlayVideoMsg
{
required string playurl = 2;
required int32 playspeed = 3;
}
message OPlayImageMsg
{
required string playurl = 2;
}