流程图
ClientBootstrap
package com.netty.dubboRPC.customer;
import com.netty.dubboRPC.netty.NettyClient;
import com.netty.dubboRPC.publicInterface.HelloService;
public class ClientBootstrap {
//协议头
public static final String providerName = "HelloService#hello#";
public static void main(String[] args) throws InterruptedException {
//创建一个消费者
NettyClient customer = new NettyClient();
//创建代理对象
HelloService service = (HelloService) customer.getBean(HelloService.class, providerName);
for (; ; ) {
Thread.sleep(2 * 1000);
//通过代理对象调用服务提供者的方法
String res = service.hello("你好,dubbo");
System.out.println("调用结果 res:" + res);
}
}
}
NettyClient
package com.netty.dubboRPC.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NettyClient {
//线程池
private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static NettyClientHandler client;
//使用代理模式,获取代理对象
public Object getBean(final Class<?> serviceClass, final String providerName) {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{serviceClass}, (proxy, method, args) -> {
//此段{}中的代码,客户端每调用一次hello,就会进入该代码
if (client == null) {
initClient();
}
//设置发给服务端信息,providerName协议头,args[0]是客户端调用api hello(?)中的参数
client.setPara(providerName + args[0]);
return executor.submit(client).get();
});
}
//初始化客户端
private static void initClient() throws InterruptedException {
client = new NettyClientHandler();
//创建EventLoopGroup
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new StringDecoder())
.addLast(new StringEncoder())
.addLast(client);
}
});
b.connect("127.0.0.1", 7000).sync();
//ChannelFuture f = b.connect("127.0.0.1", 7000).sync();
//f.channel().closeFuture().sync();
} finally {
//group.shutdownGracefully();
}
}
}
NettyClientHandler
package com.netty.dubboRPC.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import javax.swing.plaf.IconUIResource;
import java.util.concurrent.Callable;
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {
private ChannelHandlerContext context;
private String result;//返回结果
private String para;//传入参数
@Override
public void channelActive(ChannelHandlerContext ctx) {
context = ctx;
}
@Override
public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) {
result = msg.toString();
notify();
}
@Override
public synchronized Object call() throws Exception {
context.writeAndFlush(para);
//context.writeAndFlush(Unpooled.copiedBuffer(para, CharsetUtil.UTF_8));
wait();
return result;
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
void setPara(String para) {
this.para = para;
}
}
HelloServiceImpl
package com.netty.dubboRPC.provider;
import com.netty.dubboRPC.publicInterface.HelloService;
public class HelloServiceImpl implements HelloService {
//private int count = 0;
private static int count = 0;
@Override
public String hello(String msg) {
if (msg != null) {
return "您好客户端,我已收到:" + msg + "第" + (++count);
} else {
return "您好客户端,我收到null";
}
}
}
ServerBootstrap
package com.netty.dubboRPC.provider;
import com.netty.dubboRPC.netty.NettyServer;
//启动服务提供者
public class ServerBootstrap {
public static void main(String[] args) throws Exception {
NettyServer.startServer("127.0.0.1", 7000);
}
}
HelloService
package com.netty.dubboRPC.publicInterface;
public interface HelloService {
String hello(String msg);
}