端口统一与持久性通道

时间:2013-08-26 13:54:38

标签: netty

我正在尝试将Port Unification示例改编为我的代码库。我认为我遇到的问题是在客户端和客户端之间保持通道畅通。服务器,直到服务器关闭或客户端完成其任务,或者更具体地说,整个时间使用相同的管道。因此,从管道中删除unifier处理程序的示例中的工作流程不起作用。

我在端口统一示例中看到的问题是我的客户端保持预先挂起每个请求的魔术字节,但服务器端通道删除了端口统一处理程序一旦消息进入的第一个请求被确定为有效的协议消息。通过通道的后续消息(包含来自客户端的前缀魔术字节)无法处理,因为统一处理程序不再在管道中消耗魔术字节,从而导致消息格式错误。

我能够通过将统一处理程序留在管道中来解决这个问题,但是,每当嗅探器识别出协议时,它就会添加协议处理程序。由于管道在通道的生命周期内是持久的,我一遍又一遍地添加相同的处理程序。通过向通道添加属性以避免向管道重新添加内容,这很容易解决。

现在我遇到的问题是分成几个缓冲区的消息。如果客户端将2k字节分成两条消息。第一条消息被正确地嗅探并传递到下一个处理程序(LengthFieldBasedFrameDecoder,具体)。它没有所有的字节,所以它等待其余的。当下一条消息进入剩下的字节时,因为我无法从管道中删除统一器,我再次嗅探,并且嗅探失败。

是否有针对此的解决方法,或更好的方法来完成同样的事情?

更新:

将魔术字节的消耗从统一者中移出似乎是正确的方法,但仍然是问题(或似乎是),动态改变管道在netty 4中的工作方式与在netty 3。

我的客户端协议在所有具有字节序列的请求前面进行识别。使用netty 3,我们只是跳过ChannelBuffer中的字节,删除了unifier并添加了适当的协议处理来为该请求提供服务。所有后续请求都发生了同样的事情,并且运行得很好。

但是,对于netty 4,一旦我们从处理魔术字节的管道中删除了处理程序,它就会在通道的生命周期中消失,该通道一直持续到客户端关闭它。所以在看起来管道/ ChannelHandlerContext对于通过频道的每条消息都是新的之前,每次重复使用它,我认为这就是问题所在。

afaict,这使得这种类型的管道动态变化在实践中变得困难或不可能。我想要的东西只消耗每个请求的前N个字节,但是我不能把它留在管道中,因为分成几个ByteBuf的大量请求都会吃掉它们的前N个字节,这严重破坏了它。

更新2:我认为我现在看到的行为与我在后续主题中提到的行为有关:how to manage a prefixed byte sequence which identifies your protocol

1 个答案:

答案 0 :(得分:1)

端口统一示例不期望客户端切换协议。如果你真的想要支持它,你必须想出一个机制让客户说:“我现在已经完成了使用这个特定协议,下一条消息可能使用不同的协议”,然后让PortUnificationServerHandler重新插入清除的管道。

更新:

再次阅读该场景后,我认为你的问题是你的统一处理程序消耗了“魔术字节”。它不应该。 Netty的例子没有。 unifictaion处理程序应该只确定协议,安装corrcet处理程序序列并退出。新的处理程序序列应该看到第一个字节缓冲区不变,即不应该消耗任何字节。