1

根据我们的协议,我实现了自己的帧解码器来解析通过 UDP 套接字(使用 NioDatagramChannelFactory 和 ConnectionlessBootstrap)接收到的字节。为了在接收消息时跟踪服务器中发生的情况,我在解码器的每个回调方法中添加了跟踪日志。

似乎对于服务器接收到的几乎每条消息,我们都可以看到在方法 channelInterestChanged() 中收到了两次事件“channelInterestChanged”。事件的值首先是 0 (OP_NONE),然后是 1 (OP_READ)。

我阅读了有关此的文档,但我仍然不确定为什么我会收到此类事件。我第一次通过它是因为接收缓冲区(或选择器队列)已满,但服务器接收此事件的次数与它接收“messageReceived”事件的次数相同(在调用 decode() 方法之前)和所有消息/frames 按预期正确解码。当消息丢失时,我根本看不到任何事件。在这种情况下,可能是因为数据报套接字的接收缓冲区已满。但即使我增加了这个接收缓冲区,我仍然会看到这些事件并错过消息。

所以,我想知道为什么对于收到的每条消息,服务器还会收到两个“channelInterestChanged”,一个带有 OP_NONE 值,一个带有 OP_READ 值。请注意,在通道管道中,在我的帧解码器之后,有一个 ExecutionHandler 和另一个特定于业务的处理程序(它将 JMS 消息发送到 ActiveMQ 实例)。

对我有什么想法或解释吗?

谢谢你。

4

1 回答 1

0

When a DownStreamChannelStateEvent fired from a handler (e.g calling channel.setReadable(), channel.setWriteable()), the event will change the channel's nio selector key's interested option in the NioDatagramWorker, later, a UpstreamChannelStateEvent will be fired with changed option (i.e OP_READ or OP_NONE)

Your frame decoder handler receives UpstreamChannelStateEvents because, some other handlers in the pipeline are changing the channel's read interest options (the purpose of calling channel.setReadable/setWriteable is, throttling the read/write to avoid congestion, OutOfMemoryError in the application).

If you have any MemoryAwareThreadPoolExecutor in your pipeline (which monitors the size of the channel memory used), it may suspend or resume reading by calling channel.setReadable() any time if the channel receives messages too fast. You may have to configure the MATPE instance with optimum maxChannelMemorySize, maxTotalMemorySize or disable it by setting it to 0.

于 2012-03-17T08:35:17.527 回答