Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

上一章的问题:在处理器中new ProtobufDecoder()这个解码已经写死了,所以很难再进行一个其他参数类型的解码,也就是说,如果我在.proto 的配置文件中再加一个message person2进去你会发现当这个类型进入到处理器之后,处理器只能识别一个,那这又该怎么处理呢?

在官方提出了一种处理方式:自定义一个协议,假设当“ab”进来之后,它被认为是一种类型,当“bc”进来之后,它又被认为是另外一种类型。这个自定义协议的难度有点大,较为复杂。

现在用先进使用比较多的方式来解决这个问题,先写代码,然后一步步跟你们讲解

首先修改一下代码,将protobuf中的类型全部换成optional,这是官方比较支持的形式(和我们当前的问题关系不大)
Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

 现在开始解决,看到下面的代码可能大部分人应该已经懂了,我们通过枚举来进行判断我们使用的是哪个类型

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

 通过data_type这个变量来保存传递的变量值

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

使用oneof

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

它相当于optional,可选值,它最主要的特点就是缓存中只保存一个值,其他值都会被清理到

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

protobuf的例子:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

代码添加:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

编译生成代码:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题 现在我们传递的参数就是MyMessage,记得服务端和客户端都要修改哦

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

 Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

在随机数的情况下创建person对象:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题 现在通过下面这个代码来解释一下上面写的这段代码:

首先创建一个MyMessage的实例,这个问题不大,大家应该能够理解。接下来就是创建是一个setDataType(),这里大家千万别以为这个DataType()是enum DataType,如果这样理解的话,那就打错特错了!

这里我们得考虑到一个很重要的问题,在protobuf里面不建议我们使用驼峰命名法,因为在protobuf中,例如我们定义的data_type,当它被java转义之后,它就会自动命名为驼峰类型,也就是dataType;

回到上面那个继续分析,setDataType()就是DataTape data_type。现在能够理解了吧。

继续往下分析,设置好了data_type的值为枚举值1也就是person,这样一一对应下来就是oneof dataBody里面的Person。因为person类型与MyMessage是同级别的,所以时间在MydataInfo上面和DataType创建方式一样,赋值给set方法中就可以了。

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

后面的cat和dog的创建原理同person一样:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

修改客户端、服务端的传入类型为message(很多地方我就不截图了,你们自己注意就好):

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题 在处理器中将信息进行处理:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

启动服务器、客户端:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

连续重启之后:

Netty的深入浅出--10.接上一篇netty与protobuf整合的问题

问题是解决了,但是很多人就会想了,如果类型很多的话那怎么,难得要一个个的判断吗?

这个问题问的好,确实是,当前网上技术来说 我们确实只能这样来做,没有什么更好的办法。

那为什么会出现这种情况呢?

你们可以想想,一信息从远程或者缓存中发送到服务器,服务器首先你得告诉服务器它是什么类型,这样服务器才能够解析,不然某个客户端随便发个信息给你,后台都能接收,那它该如何选择保存类型呢?这些问题纠结起来,最后还是要求发送的告诉的类型一定得说明。

但问题又来了,这种RPC的方式不是和spring 中的getMapping()和postMapping()很相似吗?

原理确实是一样的,在spring和springMvc框架底层其实和我们上面写的差不了,就是判断,而springMvc中有一个类dispatcherServer这个控制类完成,也就是说通过大量的代码将它们很好的封装起来了。而protobuf和netty却是一个原生的框架而已。很多东西都必须由使用者自己来判断。