В обработчике сервера у меня есть следующий метод:
private void writeResponse(HttpObject currentObj, ChannelHandlerContext ctx) throws Exception {
Promise<String> promise = client.run(); // client.run() will return a promise
// the promise contains the result string I need for http response.
promise.sync();
// this method sends http response back, promise.getNow() is the content for the response.
writeResponse(currentObj, ctx, promise.getNow());
}
Этот метод заключается в отправке ответа после получения некоторых данных от клиента (client
в коде).И когда я проверял это с помощью браузера, я получал содержимое ответа.
Однако, когда я изменил его на:
private boolean writeResponse(HttpObject currentObj, ChannelHandlerContext ctx) throws Exception {
Promise<String> promise = client.run();
promise.addListener(new FutureListener<String>() {
@Override
public void operationComplete(Future<String> future) throws Exception {
if (future.isSuccess()) {
writeResponse(currentObj, ctx, future.getNow()); // (1)
} else {
writeResponse(currentObj, ctx, "FAILED");
}
}
});
}
, он больше не работал.Насколько я понимаю, второй также должен работать, потому что я подтвердил, что код действительно ввел блок (1) (блок if (future.isSuccess())
).Но я не получил никакого ответа в браузере.Может кто-нибудь объяснить это немного или указать мне на некоторые ссылки?Я нашел сравнение между await()
и addListener
в документе, но мне кажется, что они похожи друг на друга по функциям.
Спасибо!
[обновление] Я обнаружил, что это из-за этого метода перегрузки:
private void writeResponse(HttpObject currentObj, ChannelHandlerContext ctx, String content) {
FullHttpResponse response = new DefaultFullHttpResponse(
HTTP_1_1, currentObj.decoderResult().isSuccess()? OK : BAD_REQUEST,
Unpooled.copiedBuffer(content, CharsetUtil.UTF_8));
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
if (HttpUtil.isKeepAlive(request)) {
// Add 'Content-Length' header only for a keep-alive connection.
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
}
ctx.write(response);
}
Я не должен использовать ctx.write (ответ), но использовать ctx.writeAndFlush (ответ).
Сначала яиспользуйте ctx.write (response), потому что у меня есть метод readComplete
для выполнения сброса для меня.
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
Но кажется, что при использовании addListener
вместо sync
, channelReadComplete
не можетсделать флеш.Есть идеи почему?