gpt4 book ai didi

java - Netty 自定义 DelimiterBasedFrameDecoder

转载 作者:太空宇宙 更新时间:2023-11-04 06:49:31 31 4
gpt4 key购买 nike

我的公司正在探索使用 Netty 框架来实现消息路由器的可能性。它将路由的消息来自许多不同的来源,并且都有自己的格式。在大多数情况下,消息采用 XML 格式,其中包含包含正文长度的 header 。然而,我们有一个供应商的消息不同,并且不包含正文的长度。

这一供应商消息包含标题、正文和预告片。 header 为 1 个字节,为 STX (0x02)主体长度可变尾部为 2 个字节,其中包含 ETX(0x03),后跟 LRC。

因此,典型的消息可能如下所示:

STX   BODY   ETX  LRC
02 37000000 06 18

我们最初使用 DelimiterBasedFrameDecoder 将 ETX 定义为分隔符,但是当我们这样做时,我们会丢失作为消息一部分的 LRC 字节。结果,LRC 最终成为我们解码的下一条消息的第一个字节。有没有办法使用 DelimiterBasedFrameDecoder 并读取 ETX 分隔符之后的一个字节?

此外,当我们将响应发送回源时,源将向我们发送一个 ACK​​,我们也必须用 ACK 进行响应。

我认为我们需要一个自定义解码器来读取字节,如果它是 ACK,则它会通知下一个处理程序,否则,它会继续读取,直到读取 ETX 后面的 1 个字节,然后将该消息发送到下一个处理程序。这看起来合理吗?有没有更好的方法或者 Netty 中是否有一个解码器我可能想使用而不是 DelimiterBasedFrameDecoder?

如果我能得到任何帮助,我将不胜感激!

更新

因此,根据 Norman 的建议,我创建了以下解码器:

public class MyDecoder extends DelimiterBasedFrameDecoder{

public MyDecoder(int maxFrameLength, boolean stripDelimiter, ByteBuf delimiter) {
super(maxFrameLength, stripDelimiter, delimiter);
this.setSingleDecode(true);
}

@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
Object frame = super.decode(ctx, buffer);
ByteBuf bufFrame = null;

if(frame instanceof ByteBuf){
bufFrame = (ByteBuf)frame;

}else{
System.out.println("OBJECT TYPE: " + frame.getClass().getSimpleName());
}

byte lrc = buffer.readByte();
bufFrame.writeByte(lrc);
return bufFrame;
}

public MyDecoder(int maxFrameLength, ByteBuf delimiter) {
super(maxFrameLength, delimiter);
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
System.out.println("VERIFONE DECODER READY");
}
}

我的处理程序使用以下内容初始化...

public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {

ByteBuf delimiter;
byte[] ETX = {0x03};
byte[] STX = {0x02};

@Override
protected void initChannel(SocketChannel ch) throws Exception {
setupDelimiter();
ch.pipeline().addLast(new MyDecoder(65*1024, false, delimiter));
ch.pipeline().addLast(new ByteArrayDecoder());
ch.pipeline().addLast(new ByteArrayEncoder());
ch.pipeline().addLast(new MyHandler());
}

private void setupDelimiter(){
delimiter = Unpooled.copiedBuffer(ETX);

}

}

一切都按预期工作,我收到了完整的消息,包括 ETX 之后的 1 个字节的 LRC,但是,它抛出以下异常...

May 09, 2014 5:11:43 PM io.netty.channel.DefaultChannelPipeline$TailHandler exceptionCaught
WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It
usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.DecoderException: java.lang.NullPointerException
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:258)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:140)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:74)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:138)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:320)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at com.test.MyDecoder.decode(MyDecoder.java:33)
at io.netty.handler.codec.DelimiterBasedFrameDecoder.decode(DelimiterBasedFrameDecoder.java:216)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:227)
... 11 more

我不知道为什么会发生这种情况......

对我应该看什么有什么想法吗?

最佳答案

您将需要自己的 DelimiterBasedFrameDecoder 版本来处理这种情况。基本上只是 Netty 附带的副本,但在分隔符后还多消耗 1 个字节。

关于java - Netty 自定义 DelimiterBasedFrameDecoder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23528826/

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