首页 > 解决方案 > 在 channelFuture 上调用同步不会阻塞线程

问题描述

我有一个连接到远程服务器以进行请求-响应周期的 netty 客户端。我想阻止直到远程连接成功并且我已经解析了响应。

这是我所做的

Channel ch = bootstrap.connect(addr).sync().channel();
            ChannelFuture f = ch.writeAndFlush(obj);
            f.sync();
            f.channel().close();
       System.out.println("hello world");

在我的处理程序上

MyHandler extends ChannelInboundHandlerAdapter {

     static Map<String,Object> = new HashMap<>();
       @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) {
       System.out.println("foo bar");
        if (msg instanceof FullHttpResponse) {
            parseAndPutInMap(msg);
         }
        ctx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }
}

我观察到的是调用 f.sync() 没有阻塞。我看到在“foo bar”之前立即打印了“hello world”。我还浏览了调试器,但在调用 f.sync() 后没有看到 channelRead 命中。

那么这里有什么问题呢?我希望这个操作被阻塞,因为我需要在决定做什么之前处理响应。

标签: netty

解决方案


您的操作实际上是阻塞的,它一直等到“写入”完成。

但这对您来说是个问题,因为您想等到“阅读”完成。

您可以做的一件事是在通道的未来“同步”,然后在您完成阅读后关闭您的读取处理程序中的通道。

Channel ch = bootstrap.connect(addr).sync().channel();
ChannelFuture f = ch.writeAndFlush(obj);
f.sync(); // Also sync on this, so its error automatically get thrown
ch.closeFuture().sync();
System.out.println("hello world");
MyHandler extends ChannelInboundHandlerAdapter {

     static Map<String,Object> = new HashMap<>();
       @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) {
       System.out.println("foo bar");
        if (msg instanceof FullHttpResponse) {
            parseAndPutInMap(msg);
         }
        // The following line automatically closes the channel:
        ctx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }
}

推荐阅读