服务消费端
客户端我们需要4个类:
客户端启动类:客户端发起请求,开启远程调用,显示调用结果
RPC动态代理类:创建代理对象,封装request请求对象,创建RpcClient对象,
客户端业务处理类:主要是发送消息到服务端,接收服务端返回的消息
Netty启动类:连接netty服务端,提供消息发送等方法,并且可以自定义传输协议。
Netty启动类
package cn.itsource.consumer;
import cn.itsource.protocol.MyInvokerProtocol;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author : pankun
* @Version : 1.0
**/
public class RpcClient implements InvocationHandler {
private Class<?> clazz;
public RpcClient(Class<?> clazz){
this.clazz = clazz;
}
// 动态代理执行相应业务逻辑
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(Object.class.equals(method.getDeclaringClass())){
// 如果当前就是一个实现类
return method.invoke(proxy,args);
}else{
return rpcInvoke(method,args);
}
}
private Object rpcInvoke(Method method, Object[] args) {
MyInvokerProtocol request = new MyInvokerProtocol();
request.setClassName(this.clazz.getName()); // 类名称
request.setMethodName(method.getName()); // 方法名称
request.setParames(method.getParameterTypes()); // 入参列表
request.setValues(args); // 实参列表
// TCP 远程调用
final RpcClientHandler consumerHandler = new RpcClientHandler();
NioEventLoopGroup work = new NioEventLoopGroup();
Bootstrap server = new Bootstrap();
server.group(work)
.channel(NioSocketChannel.class)// 客户端管道
.option(ChannelOption.TCP_NODELAY, true) // 开启
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
//自定义协议编码器
pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
//对象参数类型编码器
pipeline.addLast("encoder", new ObjectEncoder());
//对象参数类型解码器
pipeline.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));
pipeline.addLast("handler",consumerHandler);
}
});
ChannelFuture future = null;
try {
future = server.connect("localhost", 8082).sync();
future.channel().writeAndFlush(request).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
work.shutdownGracefully();
}
return consumerHandler.getResponse();
}
}
免责声明:部分文章信息来源于网络以及客户意见反馈,本站只负责对文章进行整理、排版、编辑,出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性,如本站文章和转稿涉及版权等问题,请作者在及时联系本站,我们会尽快联系您处理