【发布时间】:2014-05-24 18:34:58
【问题描述】:
在我们的应用程序中,我们有一个客户端/服务器对,它们使用小型握手协议 P1 启动它们的连接,然后切换到另一个协议 P2。
对于 P1 协议,管道使用以下处理程序进行初始化:
LengthFieldBasedFrameDecoder
P1ProtocolMessageDecoder
LengthFieldPrepender
P1ProtocolMessageEncoder
P1 握手协议成功完成后,流量应该切换到 P2 协议,在这种情况下,我们首先清除管道,然后添加一组单独的处理程序
P2MessageDecoder
P2MessageEncoder
IdleHandler
在收到 P1 协议中的最后一个预期消息时完成管道切换:
// switch traffic to P2 protocol
clearPipeline();
addNewHandlers();
遇到的问题是删除 LengthFieldBasedFrameDecoder 会触发意外读取(因为处理程序的 ByteBuf 中有未读取的字节)。但是,由于在那个时间点,管道是空的(已被清除,但尚未添加新的处理程序),入站消息被丢弃。
在处理程序还没有到位期间,是否有任何“安全”的方式来进行管道切换而不会触发不需要的读取?
谢谢
稍后编辑:
我在此处阅读了有关更换解码器的信息: (标题为“在管道中用另一个解码器替换一个解码器”的部分)
http://netty.io/4.0/api/io/netty/handler/codec/ReplayingDecoder.html
我成功申请的解决方法是:
removeOldNonByteToMessageHandlers();
addNewHandlers()
removeOldByteToMessageHandlers();
// when the "leftover bytes" read is triggered the new handlers are already in place
我的解决方案似乎很老套。 有没有更好的“netty-er”方式来实现这一目标?
【问题讨论】:
-
这是 netty 3 的问题吗?
-
不,很抱歉造成混乱。问题是关于 Netty 4。javadoc 链接来自 v3,它很好地解释了行为并且对 v4 也有效 - 只是组件在 v4 中的命名不同netty.io/4.0/api/io/netty/handler/codec/…
-
我也对这个问题的一个好答案非常感兴趣,因为我有完全相同的用例,而且一开始的握手会让一切都变得有点 hacky。