【问题标题】:Netty pipeline switching/replacing in a safe way (without dropping messages)以安全的方式切换/替换 Netty 管道(不丢弃消息)
【发布时间】: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。

标签: netty pipeline


【解决方案1】:

我注意到删除订单中的 ByteToMessage 处理程序对我来说还不够,因为它仍会尝试将它们用于当前消息中的剩余字节。

在我的情况下,我有一个 FixedLengthFrameDecoder,我想在读取指定的字节数后切换为 LengthFieldBasedFrameDecoder。

如果我的消息是 X 字节,第一个字节是协议信号或“握手”,Z 是剩余字节数,我想用 ByteToMessage 处理程序读取第一个 Y,然后是 Z 下一个字节由新的处理程序。

@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
    Object handshake = super.decode(ctx, in);

    ctx.pipeline().addFirst(new LengthFieldBasedFrameDecoder(ByteOrder.BIG_ENDIAN, Integer.MAX_VALUE, 0, 4, 0, 4, true));
    if (in.isReadable()) {
        Object[] response = new Object[] { in.readBytes(in.readableBytes())};
        ctx.pipeline().remove(this);
        return response;
    } else {
        ctx.pipeline().remove(this);
        return handshake;
    }

}

【讨论】:

    猜你喜欢
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2014-06-08
    相关资源
    最近更新 更多