How to get server response with netty client

后端 未结 3 1403
孤街浪徒
孤街浪徒 2020-12-05 00:54

I want to write a netty based client. It should have method public String send(String msg); which should return response from the server or some future - doesen\'t

3条回答
  •  [愿得一人]
    2020-12-05 01:52

    You can find the sample in netty project. We can save the result into the last handler's custom fields. In the following code, it is handler.getFactorial() that is what we want.

    refer to http://www.lookatsrc.com/source/io/netty/example/factorial/FactorialClient.java?a=io.netty:netty-all

    FactorialClient.java

    public final class FactorialClient {
    
        static final boolean SSL = System.getProperty("ssl") != null;
        static final String HOST = System.getProperty("host", "127.0.0.1");
        static final int PORT = Integer.parseInt(System.getProperty("port", "8322"));
        static final int COUNT = Integer.parseInt(System.getProperty("count", "1000"));
    
        public static void main(String[] args) throws Exception {
            // Configure SSL.
            final SslContext sslCtx;
            if (SSL) {
                sslCtx = SslContextBuilder.forClient()
                    .trustManager(InsecureTrustManagerFactory.INSTANCE).build();
            } else {
                sslCtx = null;
            }
    
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group)
                 .channel(NioSocketChannel.class)
                 .handler(new FactorialClientInitializer(sslCtx));
    
                // Make a new connection.
                ChannelFuture f = b.connect(HOST, PORT).sync();
    
                // Get the handler instance to retrieve the answer.
                FactorialClientHandler handler =
                    (FactorialClientHandler) f.channel().pipeline().last();
    
                // Print out the answer.
                System.err.format("Factorial of %,d is: %,d", COUNT, handler.getFactorial());
            } finally {
                group.shutdownGracefully();
            }
        }
    }
    
    public class FactorialClientHandler extends SimpleChannelInboundHandler {
    
        private ChannelHandlerContext ctx;
        private int receivedMessages;
        private int next = 1;
        final BlockingQueue answer = new LinkedBlockingQueue();
    
        public BigInteger getFactorial() {
            boolean interrupted = false;
            try {
                for (;;) {
                    try {
                        return answer.take();
                    } catch (InterruptedException ignore) {
                        interrupted = true;
                    }
                }
            } finally {
                if (interrupted) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            this.ctx = ctx;
            sendNumbers();
        }
    
        @Override
        public void channelRead0(ChannelHandlerContext ctx, final BigInteger msg) {
            receivedMessages ++;
            if (receivedMessages == FactorialClient.COUNT) {
                // Offer the answer after closing the connection.
                ctx.channel().close().addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) {
                        boolean offered = answer.offer(msg);
                        assert offered;
                    }
                });
            }
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    
        private void sendNumbers() {
            // Do not send more than 4096 numbers.
            ChannelFuture future = null;
            for (int i = 0; i < 4096 && next <= FactorialClient.COUNT; i++) {
                future = ctx.write(Integer.valueOf(next));
                next++;
            }
            if (next <= FactorialClient.COUNT) {
                assert future != null;
                future.addListener(numberSender);
            }
            ctx.flush();
        }
    
        private final ChannelFutureListener numberSender = new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    sendNumbers();
                } else {
                    future.cause().printStackTrace();
                    future.channel().close();
                }
            }
        };
    }
    

提交回复
热议问题