【问题标题】:Netty - calling channel.disconnect() actually closes the channelNetty - 调用 channel.disconnect() 实际上关闭了通道
【发布时间】:2012-12-17 05:24:09
【问题描述】:

我使用的是 Netty 版本 2.6.0.Final。

如果我正确理解 Netty 文档,在 Channel 上调用 disconnect() 应该允许我稍后调用 connect() 以再次连接。但是,当我调用 disconnect() 时,我的 SimpleChannelHandler 子类的 channelDisconnected() 和 channelClosed() 都会被调用。

我在调试模式下打开它,基本上事件的顺序是:

  1. 我在我的频道上调用 disconnect()
  2. Channels.disconnect() 被调用:

    public static ChannelFuture disconnect(Channel channel) {
      ChannelFuture future = future(channel);
      channel.getPipeline().sendDownstream(new DownstreamChannelStateEvent(
            channel, future, ChannelState.CONNECTED, null));
      return future;
    }
    
  3. 最终,NioSocketPipelineSink.eventSunk() 被调用,相关部分是:

        case CONNECTED:
            if (value != null) {
                connect(channel, future, (SocketAddress) value);
            } else {
                channel.worker.close(channel, future);
            }
            break;
    

因此,由于值为 null 并且状态为 CONNECTED,因此通道将关闭(尽管根据 here CONNECTED 与 null 应该表示断开连接的请求,不一定关闭。

那么我在这里遗漏了什么吗?如果 disconnect() 只是导致通道被关闭,那么它有什么意义呢?

这不是一个大问题,因为如果需要,我可以为我的情况创建一个新 Channel,但从最初的检查来看,这似乎是一个 Netty 错误,除非我只是误解了它应该如何工作或者我在做一些傻事。

【问题讨论】:

    标签: netty


    【解决方案1】:

    Netty 的一个目的是提供一个统一的 Channel 抽象,无论底层实现是 OIO、NIO 还是 AIO,它对于面向连接的套接字 (TCP) 和无连接套接字 (UDP) 的工作方式大致相同。由于存在很多差异,统一接口对于特定实现的某些部分看起来会有些奇怪。

    断开 TCP 套接字的行为意味着关闭它(至少从 Java API 的角度来看)。但是断开一个UDP套接字并不意味着关闭它,只是删除了本地IP地址/端口和远程IP地址/端口之间的关联。

    所以,不,您没有做任何愚蠢的事情,但我建议您改为对 OPEN/CLOSE 事件采取行动,除非您确实需要在其生命周期内将 UDP 套接字“连接”到不同的远程目标。

    编辑:在前面的段落中遗漏了一个重要的“不”。

    【讨论】:

    • 嗯,我想这是有道理的。我主要只是在寻找一种能够在断开连接后重用 Netty TCP 通道的方法,而不必完全重新创建整个通道和管道(并更新引用它的对象),但它可能不够昂贵,不会成为问题.
    • 一个 TCP 连接几乎总是代表一个更高级别的“紧密”连接;在大多数情况下,尝试重新使用较低级别的资源会比在较高级别的连接结束时简单地丢弃它们更多的工作和更多的混乱。
    猜你喜欢
    • 2014-07-14
    • 2021-10-29
    • 1970-01-01
    • 2015-03-21
    • 2018-06-14
    • 2017-06-23
    • 2016-12-26
    • 1970-01-01
    • 2013-12-28
    相关资源
    最近更新 更多