前言
距离上一个版本的RPC也有一两个月的时间了,中间也是在做论文的相关实验,自己也陆陆续续学习了一点Netty和其他的知识,今天记录和分享一下用Netty实现的RPC框架。在上一个博客中提到,使用NIO会有很多问题,比如Selector的空轮询、编码难度大等问题,用Netty能很好的解决以上问题,因为它把NIO很好的进行了封装,让使用者不必去考虑这么多的问题,这也是Netty的一个优势所在吧。
一、整体实现思路
首先说明一下,我这边的Netty用的是4.1的版本。RPC实现的思路和之前的大同小异。从客户端来说,仍然用到了动态代理,只不过这版中我对发送的请求做了封装,用了jdk原生的序列化方法,这块后面还可以再做优化,尝试用其他的序列化方法去做。服务端反序列化并解析请求参数,用反射去得到相应的函数调用,最终返回给客户端。
二、代码实现
客户端
封装请求MSG.java
1 | public class MSG implements Serializable { |
配置客户端的相应函数
EchoClient.java
1 | public class EchoClient { |
这边我是将请求函数的函数名、参数类型和参数直接传到EchoClientHandler中进行处理。来看EchoClientHandler.java
1 | public class EchoClientHandler extends ChannelInboundHandlerAdapter { |
EchoClientHandler中最重要的是重写的channelActive和channelRead两个方法。其中第一个是在客户端与服务端连接上之后触发的相应,就可以将请求发送过去。在服务端处理请求后返回,用channelRead来接收服务端返回的数据。
服务端
服务端的配置和客户端的类似,
同样的,为了解析请求,要封装请求MSG.java,是和客户端的一致。注意,这边由于序列化的编码与解码,MSG.java要和客户端的包位置相同,否则会报错!
1 | io.netty.handler.codec.DecoderException: java.io.InvalidClassException: failed to read class descriptor |
NettyService.java
1 | public class NettyService { |
同样的,来看看服务端的handle
EchoServerHandler.java
1 | public class EchoServerHandler extends ChannelInboundHandlerAdapter { |
这边最重要的一个函数是channelRead,这里面需要实现解析客户端发送过来请求的逻辑,并将得到的结果发送回客户端。