我读过Netty Guide,它对ChannelFuture的解释不多。我发现ChannelFuture在应用时是一个复杂的想法。
我想做的是在初始响应后将消息写到上下文中。与典型的请求/响应流不同。我需要这样的流程:
客户端发送请求->服务器(净额)
服务器使用ctx.writeAndFlush(msg)发送响应;
步骤2完成后,服务器会向该ctx发送更多消息。
问题是,如果我这样做,第二次写操作将不会发出:
ctx.writeAndFlush(response);
Message newMsg = createMessage();
ctx.writeAndFlush(newMsg); //will not send to client
然后,我尝试使用ChannelFuture,它可以工作,但是我不确定逻辑上是否正确:
ChannelFuture msgIsSent = ctx.writeAndFlush(response);
if(msgIsSent.isDone())
{
Message newMsg = createMessage();
ctx.writeAndFlush(newMsg); //this works
}
还是应该改用ChannelFutureListener()?
ChannelFuture msgIsSent = ctx.writeAndFlush(response);
msgIsSent.addListener(new ChannelFutureListener(){
@Override
public void operationComplete(ChannelFuture future)
{
Message newMsg = createMessage();
ctx.writeAndFlush(newMsg);
}
});
这也行吗?
最佳做法是哪一种?使用方法2是否有任何潜在问题?
最佳答案
当然,这也取决于您的“协议”(例如,如果您使用HTTP,则HTTP协议不支持为同一请求发送2个answear)。但是,可以说您的协议允许您发送多个响应部分:
Netty添加消息发送到管道,遵守顺序。
因此,在您的第一个示例中,我有点惊讶它不起作用:
ctx.writeAndFlush(response);
Message newMsg = createMessage();
ctx.writeAndFlush(newMsg); // should send the message
但是,可能由您的协议引起。例如,这可能发生:
response in message queue to send
flush not yet done
newMsg in message queue to send
flush now come but protocol does not support 2 messages so only send first one
因此,如果您的协议必须承认已经发送了第一条消息,那么您必须等待第一条消息,因此可以执行以下操作:
ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (future.isDone()) {
Message newMsg = createMessage();
ctx.writeAndFlush(newMsg);
} else { // an error occurs, do perhaps something else
}
}
});
因此,您的最后一个建议(我只是不创建ChannelFuture,而是直接使用writeAndFlush的结果,但两者相等)。只需要注意operationComplete并不意味着成功的情况。