protocol buffer应用场景方案想法

刚进公司,给了个活,了解protocol buffer,应用这个技术给通信做打包和拆包

现在还没拿到公司这块的代码,但是对于工业物联网的项目,报文的消息应该是多样的,用端对端都是同一个消息体显然是不切实际的

那就是接下来的问题了目前想到三个解决方式

两端都维护消息体的protocol生产的java文件,在生产的byte数组前,两外加一些字节负责存放这个类的一些信息,以便接收方可以知道接收的数据属于哪个实体类

这种方式又出现两个解决方式,一是傻瓜式得维护一个类似switch case的方式,通过消息体带的标识,直接转到哪个分支,用什么类去反解成实体类,这个方式最大的缺点就是需要维护这个Switchcase,对修改不友好

第二种方式是,获得类的信息,通过反射的方式,得到类,调用反解方法

说到第二种方式,在网上查到的通过标记类信息反解,用descriptor的方式来做,就有点疑惑,既然我能拿到类的信息,为啥我还要用descriptor来搞反解,为啥不一步到位直接调用这个对象反解

 

第三种方式就是动态解析

 如下就是一个,在用descriptor解析获得一个dynamicMessage后,还需要拼接成一个对象,可能对于json格式的比较合适

protobuf在java应用中通过反射动态创建对象(DynamicMessage)

下方是一个dynamicMessage的应用场景的demo集合

Java Code Examples for com.google.protobuf.DynamicMessage

说一下descriptorSet生成的两种方式  :

相对路径 protoc --descriptor_set_out=cinema.description ./cinema.proto --proto_path=.
绝对路径 protoc --descriptor_set_out=D://cinema1.description D://cinema1.proto --proto_path=D://
贴两个利用生成的descriptor来实现反解的例子

Protobuf动态解析、自描述消息(java版)

Protobuf动态解析在Java中的应用 包含例子程序

这两个例子非常相似,问题在于我的proto定义里有使用其他的message,跑这个demo的时候直接挂了,报找不到那个message的定义

反而采用下方这种,从生成的protojava类里获取的descriptor反解没有报错,这三个例子都有很多短板

做了两次包装和反解,还需要利用反射,性能上损耗应该很大

 static void sendAndRead2(byte[] ba) throws InvalidProtocolBufferException {

        Descriptors.Descriptor descriptor=Ownerpro.Owner.getDescriptor();
        DynamicMessage dynamicMessage=DynamicMessage.parseFrom(descriptor,ba);
        System.out.println(descriptor.getFullName());
        System.out.println(descriptor.getIndex());
        System.out.println(dynamicMessage.getField(descriptor.findFieldByNumber(1)));
        //dynamicMessage.getField(descriptor.getIndex())
        //dynamicMessage.getField(descriptor.findFieldByNumber());
        System.out.println(dynamicMessage.getAllFields());
    }

Owner
0
ls
{Owner.name=ls, Owner.phone=33336, Owner.age=56, Owner.houses=[xiaoqu: "hubing"
lou: "15dong"
danyuan: 303
, xiaoqu: "gaoshan"
lou: "8dong"
danyuan: 201
]}

这是打印出的结果,可以看到包含了类的信息,这个要反解成对象的话,还是有点费劲

  

posted @ 2021-07-08 12:09  heroinss  阅读(396)  评论(0编辑  收藏  举报