netty客户端同步请求实现

来源:互联网 发布:写一个数组去重 编辑:程序博客网 时间:2024/05/16 10:22

netty客户端同步请求实现


在项目开发中经常会遇到某个请求需要立刻返回结果的请,而我们使用的框架netty是异步的,如何做到同步请求是经常会困惑到刚刚接触netty的同行。
本文使用netty4为标准实现客户端向服务器的同步请求实例。如有不合理之处望各位指正,共同进步。

客户端 SimpleChatClientHandler

package com.netty.chart;import java.util.concurrent.CountDownLatch;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.timeout.IdleStateEvent;public class SimpleChatClientHandler extends SimpleChannelInboundHandler<String> {    private CountDownLatch lathc;    public SimpleChatClientHandler(CountDownLatch lathc) {        this.lathc = lathc;    }    private String result;    @Override    protected void channelRead0(ChannelHandlerContext arg0, String arg1) throws Exception {        System.out.println("==========收到服务器消息:"+arg1);        result = arg1;        lathc.countDown();//消息收取完毕后释放同步锁    }    public void resetLatch(CountDownLatch initLathc){        this.lathc = initLathc;    }    public String getResult() {        return result;    }     @Override    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {        // IdleStateHandler 所产生的 IdleStateEvent 的处理逻辑.        if (evt instanceof IdleStateEvent) {            IdleStateEvent e = (IdleStateEvent) evt;            switch (e.state()) {                case ALL_IDLE:                    handleAllIdle(ctx);                    break;                default:                    break;            }        }    }    protected void handleAllIdle(ChannelHandlerContext ctx) {//        ctx.channel().writeAndFlush("1" + "\r\n");    }}

客户端 SimpleChatClientInitializer

package com.netty.chart;import java.util.concurrent.CountDownLatch;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.DelimiterBasedFrameDecoder;import io.netty.handler.codec.Delimiters;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.handler.timeout.IdleStateHandler;public class SimpleChatClientInitializer extends ChannelInitializer<SocketChannel> {    private CountDownLatch lathc;    public SimpleChatClientInitializer(CountDownLatch lathc) {        this.lathc = lathc;    }    private SimpleChatClientHandler handler;    @Override    protected void initChannel(SocketChannel channel) throws Exception {        handler =  new SimpleChatClientHandler(lathc);        ChannelPipeline pipeline = channel.pipeline();        pipeline.addLast(new IdleStateHandler(0, 0, 5));        pipeline.addLast("framer", new DelimiterBasedFrameDecoder(81920, Delimiters.lineDelimiter()));        pipeline.addLast("decoder", new StringDecoder());        pipeline.addLast("encoder", new StringEncoder());        pipeline.addLast("handler", handler);    }    public String getServerResult(){        return handler.getResult();    }    //重置同步锁    public void resetLathc(CountDownLatch initLathc) {        handler.resetLatch(initLathc);    }}

客户端 SimpleChatClient

package com.netty.chart;import java.util.concurrent.CountDownLatch;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.handler.codec.Delimiters;public class SimpleChatClient {    private final String host;    private final int port;    public SimpleChatClient(String host, int port) {        this.host = host;        this.port = port;    }    public void run() throws Exception {        EventLoopGroup group = new NioEventLoopGroup();        try {            CountDownLatch lathc = new CountDownLatch(1);            SimpleChatClientInitializer clientInitializer = new SimpleChatClientInitializer(lathc);            Bootstrap bootstrap = new Bootstrap().group(group).channel(NioSocketChannel.class)                    .handler(clientInitializer);            ChannelFuture connect = bootstrap.connect(host, port);            Channel channel = connect.sync().channel();//          BufferedReader in = new BufferedReader(new InputStreamReader(System.in));                channel.write("bbbbbb啊啊啊" + "\r\n");//              connect.awaitUninterruptibly();//              Void void1 = connect.getNow();//              System.out.println(void1.toString());                channel.flush();                lathc.await();//开启等待会等待服务器返回结果之后再执行下面的代码                System.out.println("服务器返回 1:" + clientInitializer.getServerResult());                Thread.sleep(30000);                lathc = new CountDownLatch(1);//此处为控制同步的关键信息,注意此对象的流转                clientInitializer.resetLathc(lathc);                channel.write("bbbbbb啊啊啊1111" + "\r\n");                channel.flush();                lathc.await();                System.out.println("服务器返回 2:" + clientInitializer.getServerResult());        } catch (Exception e) {            e.printStackTrace();        } finally {//          group.shutdownGracefully();        }    }    public static void main(String[] args) throws Exception {        new SimpleChatClient("127.0.0.1", 8888).run();    }}

本文的服务端使用的是官方文档上的demo,如果需要请参考netty实现实时聊天

1 0