customer端:
接口:
public interface Hello {
String sayHi(String message);
}
实现类:
public class Customerimpl implements Hello {
@Override
public String sayHi(String message) {
return null;
}
}
创建customer:
public class CustomerRpc implements InvocationHandler {
//创建线程池
private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public HandlerOfCustomer client = new HandlerOfCustomer();
//获取动态代理对象
public Object getProxy(){
initCustomer();
return Proxy.newProxyInstance(this.getClass().getClassLoader(), Customerimpl.class.getInterfaces(),this);
}
public void initCustomer(){
NioEventLoopGroup workersGroup = new NioEventLoopGroup();
try {
Bootstrap cbootstrap = new Bootstrap();
cbootstrap.group(workersGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY,true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
pipeline.addLast(client);
}
});
cbootstrap.connect("127.0.0.1",8899).sync();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
client.setArg(args[0]);
return executor.submit(client).get();
}
}
customer处理器:
public class HandlerOfCustomer extends ChannelInboundHandlerAdapter implements Callable {
String arg;
ChannelHandlerContext chc;
String mess;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
this.chc = ctx;
}
@Override
public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
mess = msg.toString();
notify();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
@Override
public synchronized Object call() throws Exception {
chc.writeAndFlush(arg);
wait();
return mess;
}
public void setArg(Object name){
this.arg = (String) name;
}
}
启动customer
public class StartCustomer {
public static void main(String[] args) {
CustomerRpc rpc = new CustomerRpc();
Hello proxy = (Hello)rpc.getProxy();
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
String recive = proxy.sayHi(name);
System.out.println(recive);
}
}
Provider端
接口:
public interface Hello {
String sayHi(String message);
}
实现类:
public class Helloimpl implements Hello {
@Override
public String sayHi(String message) {
Long base = Long.valueOf(message);
long sum = LongStream.rangeClosed(0L, base).parallel().reduce(0, Long::sum);
return "Total:"+String.valueOf(sum);
}
}
创建provider
public class ProviderRpc {
String hostname;
int port;
public ProviderRpc(String hostname,int port){
this.hostname = hostname;
this.port = port;
initProvider();
}
public void initProvider() {
NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap sbootstrap = new ServerBootstrap();
sbootstrap
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new HandlerOfProvider());
}
});
ChannelFuture channelFuture = sbootstrap.bind(hostname, port).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
provider处理器:
public class HandlerOfProvider extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("客户发来的消息是:"+msg);
Helloimpl hi = new Helloimpl();
String result = hi.sayHi((String) msg);
ctx.writeAndFlush(result);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
provider启动类
public class StartProvider {
public static void main(String[] args) {
ProviderRpc rpc = new ProviderRpc("127.0.0.1", 8899);
}
}
上面的例子是: customer端想完成一个任务:从键盘中任意输入数字N,然后算出1+2+3+…+N的值,但是customer又不想自己算,于是他就委托provider算,provider把得到的结果返回给customer即可
上面的例子也是本主机与本主机之间的通信,下面要展示是本主机与阿里云服务器上的通信:1、 把provider放在阿里云服务器启动,记得修改开启的端口号(将127.0.0.1 —>0.0.0.0) 2、修改customer连接的IP,把127.0.0.1改成阿里云服务器的公网IP
customer端:
provider端: