我读过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个a​​nswear)。但是,可以说您的协议允许您发送多个响应部分:

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并不意味着成功的情况。

10-01 01:48