我正在使用在管道开头有LengthFieldBasedFrameDecoder
的netty 4编写代理。代理需要在将消息发送到下一个服务器之前对其进行解码。
我已将autoRead
设置为false,并在上一次写入完成时手动调用Channel.read()
,如代理示例中所示。
它似乎无法工作,如果读取不包含完整的帧,LengthFieldBasedFrameDecoder
会吞下读取。我的代理处理程序没有机会请求下一次读取,因此服务器会永远等待。
是否可以按照我想要的方式在代理中使用LengthFieldBasedFrameDecoder
,或者是否有另一种方法可以确保代理只有在可以写入下一个服务器时才会读取消息?
答案 0 :(得分:0)
这里的问题相同。这发生在netty 4.0.27。当对等写入器发送长度超过1024字节的单个消息时,读取会立即挂起。当我丢弃LFBFDecoder时,也不会发生这种情况,也不会发生AUTO_READ为真。我的initChannel方法:
final LengthFieldBasedFrameDecoder dec = new LengthFieldBasedFrameDecoder(65535, 0, 2, 0, 2, true);
final LengthFieldPrepender prep = new LengthFieldPrepender(2);
channel.pipeline().addLast(prep);
channel.pipeline().addLast(new ByteArrayEncoder());
channel.pipeline().addLast(dec);
channel.pipeline().addLast(new ByteArrayDecoder());
channel.pipeline().addLast(readerHandler);
我希望只有在收到完整的消息时才会重新发出read()(在channelRead()方法中)。
作为一种解决方法,我通过在decode()方法中添加两个读取来修改LFBFDecoder,现在它正在工作。
if (in.readableBytes() < lengthFieldEndOffset) {
ctx.channel().read(); // HERE
return null;
}
和
// never overflows because it's less than maxFrameLength
int frameLengthInt = (int) frameLength;
if (in.readableBytes() < frameLengthInt) {
ctx.channel().read(); // HERE
return null;
}