我在使用netty(带camel)时遇到了一个奇怪的错误,我们使用LengthFieldBasedFrameDecoder进行通信,客户端是来自第三方的套接字程序,我们在服务器端使用netty。
有时会将两条消息"合并"为一条消息,因此即将发布的数据都是错误的。
例如:
客户端发送两条消息:
[10] aaaaaaaaaa和[10] bbbbbbbbbb
其中[10]是长度字节,AAAAAAAAAA是数据。
但在服务器上[10] aaaaa[10]bbbbbbbbbb
似乎第一条消息被第二条消息分割了,所以解码器将数据解释为:
[10] aaaaa[10]BBBBBBBB-
和
BBBBBBBBAAAAAAAAAA。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
使得第一条消息长度正确但数据错误,第二条消息长度"BB"错误,并获得更长的数据包。
希望我描述清楚,以前有人见过这个吗?
听起来像是在两个线程中对同一个流进行写入。
好吧,这被证明是camel-nety组件的一个"bug",我稍后会发布对camel-netti项目的修复。在此之前,请小心使用camel-netty组件,特别是不要使用没有用@sharable注释标记的编码器/解码器,这会导致问题,因为状态可能在不同的连接之间共享。
您的LengthFieldBasedFrameDecoder
是否扩展了FrameDecoder
?它是单身还是单身?
事实上,我也遇到了同样的问题,我同意彼得的观点;
我查看了FrameDecoder
,发现有一个名为"cumulation"的ChannelBuffer
属性,它将共享给解码器的所有通道。
让我们看看FrameDecoder.messageReceived
方法内部:
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Object m = e.getMessage();
if (!(m instanceof ChannelBuffer)) {
ctx.sendUpstream(e);
return;
}
ChannelBuffer input = (ChannelBuffer) m; // here is the buffer from the channel
if (!input.readable()) {
return;
}
ChannelBuffer cumulation = cumulation(ctx); // here is the buffer wrapped by the FrameDecoder
if (cumulation.readable()) {
cumulation.discardReadBytes();
// where "[10]AAA[10]BBBBB" happens
cumulation.writeBytes(input);
// if code run here,we will get the wrong buffer
callDecode(ctx, e.getChannel(), cumulation, e.getRemoteAddress());
} else {
callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
if (input.readable()) {
cumulation.writeBytes(input);
}
}
}
我认为使用FrameDecoder的正确方法是使其成为多个实例。