gpt4 book ai didi

以安全的方式切换/替换 Netty 管道(不丢弃消息)

转载 作者:行者123 更新时间:2023-12-02 03:36:38 30 4
gpt4 key购买 nike

在我们的应用程序中,我们有一个客户端/服务器对,它们通过一个小型握手协议(protocol) P1 启动它们的连接,之后它们切换到另一个协议(protocol) P2。

对于 P1 协议(protocol),管道使用以下处理程序初始化:

LengthFieldBasedFrameDecoder
P1ProtocolMessageDecoder
LengthFieldPrepender
P1ProtocolMessageEncoder

P1握手协议(protocol)成功完成后,流量应该切换到P2协议(protocol),这种情况下我们先 清理管道然后添加一组单独的处理程序
P2MessageDecoder
P2MessageEncoder
IdleHandler

当接收到 P1 协议(protocol)中的最后一个预期消息时,切换管道完成:
// 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”方式来实现这一目标?

最佳答案

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

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

如果我的消息是 X 字节,其中 Y 第一个字节是协议(protocol)信号或“握手”,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;
}

}

关于以安全的方式切换/替换 Netty 管道(不丢弃消息),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22998449/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com