基于Netty的简易版RPC

简要模型

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端:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值