从IO模型到Netty笔记(七)

目的:让本地调用远程方法像是调用本地方法一样简单。

通俗来说就是实现,客户端调用服务器端方法,并且拿到返回结果。

公共接口

public interface PublicMethods {
    public String say(String msg);
}

公共接口实现类

public class PublicMethodsImpl implements PublicMethods {
    @Override
    public String say(String msg) {
        return "收到消息:"+msg;
    }
}

服务器端

public class NtServer {
    public static void main(String[] args) {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap sb = new ServerBootstrap();
            sb.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(new NtServerHandler());

                        }
                    });
            ChannelFuture channelFuture = sb.bind(6668).sync();
            channelFuture.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }

    }
}
public class NtServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("读取中……");
        if(msg.toString().startsWith("lt")){
            String res = new PublicMethodsImpl().say(msg.toString().substring(2, msg.toString().length()));
            ctx.writeAndFlush(res);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}

客户端

public class NtClient {
    private static NtClientHandler handler;
    private static ExecutorService executor = Executors.newFixedThreadPool(8);
    private static void initClient() {
        handler = new NtClientHandler();
        NioEventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(handler);
                        }
                    });
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6668).sync();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

     Object getBean(final Class<?> serviceClass,final String providerName) {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class<?>[]{serviceClass},
                (proxy, method, args) -> {
                    if(handler==null){
                        initClient();
                    }
                    handler.setMsg(providerName+args[0]);
                    return executor.submit(handler).get();
                });
    }

    public static void main(String[] args) {
        NtClient customer = new NtClient();
        PublicMethods service = (PublicMethods) customer.getBean(PublicMethods.class, "lt");
        String res = service.say("你好啊,我的世界");
        System.out.println("调用的结果 res= " + res);
    }
}
public class NtClientHandler extends ChannelInboundHandlerAdapter implements Callable {
    private ChannelHandlerContext context;
    private String result;
    private String msg;
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        context = ctx;
    }

    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        result = msg.toString();
        System.out.println("执行notify");
        notify();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    @Override
    public synchronized Object call() throws Exception {
        context.writeAndFlush(msg);
        System.out.println("执行wait");
        wait();
        return result;
    }
    public void setMsg(String msg){
        this.msg = msg;
    }
}

要点小结

主要是client端用了代理,调用实现了Callable的handler,给服务端发消息。

服务端根据接收的消息去调用方法,返回给客户端。

中间要经过必不可少的编码和解码,思想还不算太难。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值