1.生产者原理: netty服务端 + 反射
生产者是netty的服务器,当读取到客户端发送的消息后,获得客户端调用方法的详细数据,根据反射调用生产者中接口实现类的具体方法,并将返回值writeAndFlush到管道中,通过管道响应给客户端
2.消费者原理: netty客户端 + 反射 + 动态代理
消费者是netty的客户端,当需要使用到接口时,先获得接口的代理对象,调用接口的方法时,由代理对象作为netty客户端,封装参数,并调用服务端
3.依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
4.找到接口的所有实现类的API
Reflections reflections = new Reflections(packageName);
Set<Class<?>> implSet = (Set<Class<?>>) reflections.getSubTypesOf(interfaceClass);
1.服务器端
public class RPCServer {
public static void main(String[] args) {
new RPCServer().run(9999);
}
public void run(int port) {
EventLoopGroup bossGroup = null;
EventLoopGroup workerGroup = null;
try {
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel socketChannel) {
socketChannel.pipeline()
.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)))
.addLast("encoder", new ObjectEncoder())
.addLast(new RPCServerHandler());
}
});
ChannelFuture future = serverBootstrap.bind(port).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
2.服务器端业务逻辑处理类
public class RPCServerHandler extends ChannelInboundHandlerAdapter {
private static final String packageName = "com.baidu.rpc.service";
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ClassInfo classInfo = (ClassInfo) msg;
String className = classInfo.getClassName();
className = className.substring(className.lastIndexOf("."));
String interfaceName = packageName + className;
Class<?> clazz = Class.forName(interfaceName);
Reflections reflections = new Reflections(packageName);
Set<Class<?>> implSet = (Set<Class<?>>) reflections.getSubTypesOf(clazz);
if (implSet == null || implSet.size() == 0) {
System.out.println("没有匹配上");
} else if (implSet.size() > 1) {
System.out.println("匹配不唯一");
} else {
Class[] classArray = implSet.toArray(new Class[1]);
Class implClass = classArray[0];
Object impl = implClass.newInstance();
Method method = implClass.getMethod(classInfo.getMethodName(), classInfo.getMethodTypes());
Object result = method.invoke(impl, classInfo.getParams());
ctx.writeAndFlush(result);
}
}
}
3.客户端
public class RPCClient {
public static Class clazz;
public static <T> T getProxy(Class<T> cla) {
clazz = cla;
return (T) Proxy.newProxyInstance(cla.getClassLoader(), new Class[]{cla}, new MyInvocationHandler());
}
}
class MyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
EventLoopGroup workerGroup = null;
RPCClientHandler handler = new RPCClientHandler();
try {
workerGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(workerGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
socketChannel.pipeline()
.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)))
.addLast("encoder", new ObjectEncoder())
.addLast("handler", handler);
}
});
ChannelFuture future = bootstrap.connect("127.0.0.1", 9999).sync();
ClassInfo classInfo = getClassInfo(method, args);
Channel channel = future.channel();
channel.writeAndFlush(classInfo).sync();
future.channel().closeFuture();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
workerGroup.shutdownGracefully();
}
return handler.getResponse();
}
private ClassInfo getClassInfo(Method method, Object[] args) {
ClassInfo classInfo = new ClassInfo();
classInfo.setClassName(RPCClient.clazz.getName());
classInfo.setMethodName(method.getName());
classInfo.setMethodTypes(method.getParameterTypes());
classInfo.setParams(args);
return classInfo;
}
}
4.客户端业务逻辑处理类
public class RPCClientHandler extends ChannelInboundHandlerAdapter {
private Object response;
public Object getResponse() {
return response;
}
public void setResponse(Object response) {
this.response = response;
}
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
this.response = msg;
}
}
5.实体类
public class ClassInfo implements Serializable {
private String className;
private String methodName;
private Class[] methodTypes;
private Object[] params;
}