java - Netty ChannelFuture 是如何工作的?

标签 java netty future

我已阅读 Netty Guide ,ChannelFuture上就不多解释了。我发现 ChannelFuture 在应用时是一个复杂的想法。

我想做的是在初始响应后将消息写入上下文。与典型的请求/响应流程不同。我需要这样的流程:

  1. 客户端发送请求 -> 服务器(netty)
  2. 服务器使用 ctx.writeAndFlush(msg) 发送响应;
  3. 第 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有潜在的问题吗?

最佳答案

当然,这也取决于您的“协议(protocol)”(也就是说,例如,如果您使用 HTTP,则 HTTP 协议(protocol)不支持为同一请求发送 2 个答案)。但是假设您的协议(protocol)允许您发送多个响应部分:

Netty 添加消息发送到管道,遵守顺序。

所以在你的第一个例子中,我有点惊讶它不起作用:

ctx.writeAndFlush(response);
Message newMsg = createMessage();
ctx.writeAndFlush(newMsg); // should send the message

但是它可能由您的协议(protocol)引导。例如,这可能会发生:

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

因此,如果您的协议(protocol)必须承认第一条消息已发送,那么您必须等待第一条消息,因此请执行以下操作:

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 的结果,但两者是相等的)。请注意操作完成并不意味着成功的情况。

关于java - Netty ChannelFuture 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39269388/

相关文章:

kotlin - 如何在 Reactor Netty HTTP 客户端中设置 TCP Keepalive?

java - 提高JAVA中Netty服务器的性能

java - 使用 Guava 的 future 可迭代?

java - 通过 Futures 实现线程

java - 套接字和数据报 channel

Java 主目录

ssl - Clojure:使用 aleph 连接到 TLS 启用 docker 守护进程

Scala/Akka Future onComplete Success 编译器错误

java - ReplaceAll 正则表达式 替换$

java - recyclerview 中的 ViewPager