【问题标题】:Netty : Blocking call to get a connected Server Channel?Netty:阻止调用以获取连接的服务器通道?
【发布时间】:2012-05-11 11:42:56
【问题描述】:

ServerBootstrap.bind() 的调用返回一个Channel,但这不是Connected 状态,因此不能用于写入客户端。

Netty 文档中的所有示例都显示从其ChannelHandler 的事件(如channelConnected)写入Channel - 我希望能够在事件中而不是在事件之外获得连接的通道,让我们说一些使用我的服务器组件的客户端代码。一种方法是手动编写代码等待channelConnected 事件,然后复制 Channel 引用。但这可能是在重新发明轮子。

所以问题是:Netty 中是否有返回连接通道的阻塞调用?

编辑:我使用的是 Oio Channels,而不是 Nio。

【问题讨论】:

  • 为什么?在客户连接之前,您无法获得通往客户的频道,这会作为连接事件出现在您身上。为什么你认为你需要另一种机制?为什么是阻塞机制?这没有任何意义。
  • 我知道在客户端连接之前我无法获得连接的通道..这正是我提到阻塞的原因..可以说有一个外部接口需要一个连接的通道(用于编写一些东西)。服务器必须等待(阻塞)直到客户端连接并返回这个连接的通道..哪一部分没有意义?
  • 没有任何意义。如果它是客户端连接,则不能强制它发生,您必须在入站连接事件到达时对其进行处理。您可能在谈论 outbound 连接吗?到另一个服务器?
  • 它不是出站的。服务器确实在监听客户端的连接,他们最终会连接,也就是触发事件并建立连接的时候。但是服务器还必须为另一个对写入客户端感兴趣的外部接口(通过服务器)提供服务,并且它有自己的时间来请求通道..现在当这个外部接口调用服务器以获得连接的通道时,服务器有在客户端建立连接之前阻止此调用..这有帮助吗?
  • 我想到了同步线程和阻塞队列的方法。如果 Netty 有任何类似于 java.net.ServerSocket 的东西(一个阻塞调用,它返回一个准备好用于写入的 Channel),那么我也可以使用那个 API。 - 这就是为什么我的问题..知道没有这样的 API 太糟糕了..

标签: java netty


【解决方案1】:

您可以创建一个阻塞调用,但我认为您过快地诋毁了基于事件的方法。这是一个人为的例子,只是为了确保我理解你想要做什么:

  1. Netty 服务器启动
  2. DataPusher 服务启动。
  3. 当客户端连接时,DataPusher 获取对客户端通道的引用并向其写入一些数据。
  4. 客户端在连接后不久就会收到推送的数据。

或多或少正确?

为此,您的 DataPusher(或者更好的是,它的一个仆从)可以在您创建的服务器管道中注册为 ChannelHandler。使其扩展org.jboss.netty.channel.SimpleChannelHandler。处理程序可能如下所示:

DataPusher dataPusher = getMyDataPusherReference();

public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
   dataPusher.doYourThing(e.getChannel());  // do something in another thread....
}

如果您确定从 DataPusher 的角度来看它是一个阻塞调用,只需让它等待一个闩锁并让仆从放下闩锁。

不确定这是不是你要找的......

【讨论】:

  • 您发现我的用例或多或少是正确的。现在你提到的解决方案,问题是:DataPusher 并不像听起来那么简单。它有一组相关的活动要做,这意味着最好给它一个通道来编写,而不是试图将它的性质挤进一个 ChannelHandler 模具中。
  • 对。处理程序可以简单地感知“DataPusher”,因此它知道何时建立新连接以及如何将通道传递给 DataPusher。您还可以在 ChannelGroup 中注册所有连接的通道,然后 DataPusher 只需要对 ChannelGroup 的引用和在向其添加新通道时的“轻量级微调”。或者....覆盖 ChannelGroup 并添加您自己的事件处理。
【解决方案2】:

经过以上所有的交流,我仍然认为没有任何必要。

当然,您只需接受来自外部服务的连接即可;不要为任何事件注册它;然后,当另一个客户端连接时,在两个通道上注册 I/O 事件。

外部服务不知道也不关心你是否被阻塞在等待另一个连接的线程中,或者只是因为其他原因没有响应。

如果他正在给你写信,他的写无论如何都会成功,直到你的套接字接收缓冲区的大小,不管你是否阻塞,只要你没有真正从他那里读。当该缓冲区填满时,他会阻塞,直到您读取其中一些为止。

如果他正在阅读你的信息,他会阻止,直到你发送一些东西,而在此期间你正在做的事情对他来说是不可见的。

所以我认为你只需要简化你的想法,让它更符合非阻塞 I/O 的美妙世界。

【讨论】:

    猜你喜欢
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 2013-03-28
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多