Одна из вещей, о которых вам нужно знать, это то, что когда канал Netty находится в процессе закрытия, последний шаг - удаление всех обработчиков, этот шаг необходим, чтобы все процедуры очистки запускались внутри этих обработчики.
Это означает, что после закрытия канала вы не сможете получить доступ ни к одному из обработчиков в конвейере.
Внутри вашего кода вы ожидаете события, когда канал полностью закрылся, это означает, что код впоследствии имеет отношение «происходит после» к событию закрытия канала.
Одним из решений этого является создание объекта пользовательского обещания и передача его обработчику, который затем заполняет его ответом:
// Somewhere inside the application:
public static final AttributeKey<Promise<String>> RESPONSE = new AttributeKey("RESPONSE");
ChannelFuture chf = bootstrap.connect(addr);
Promise<String> p = chf.channel().eventLoop().newPromise();
chf.channel().attr(RESPONSE).set(p);
//blocking operation
Channel ch = chf.sync().channel();
ChannelFuture f = ch.writeAndFlush(obj);
//blocking operation
String responseString = p.get();
f.channel().close();
....
// Inside you handler
MyHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) {
if (msg instanceof FullHttpResponse) {
ctx.channel().attr(RESPONSE).get().setSuccess(parse(msg));
}
// The following line automatically closes the channel:
ctx.channel()
.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
}
Это решение работает, потому что, хотя канал и его атрибуты очищаются при выборе, у нас все еще есть ссылка на обещание, которое содержит конечный результат