在没有回车的情况下,ChannelPipeline中没有调用Netty FrameDecoder?

时间:2013-03-22 16:25:00

标签: java netty nio

我正在使用Netty,似乎没有调用ChannelPipeline中的FrameDecoder,除非/直到收到回车符。例如,我有以下解码器,我试图检测何时收到完整的JSON字符串:

public class JsonDecoder extends FrameDecoder {
    @Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) {
        char inChar = 0;
        ChannelBuffer origBuffer = buf.copy();
        StringBuilder json = new StringBuilder();
        int ctr = 0;
        while(buf.readable()) {
            inChar = (char) buf.readByte();
            json.append(inChar);
            if (inChar == '{') {
                ctr++;
            } else if (inChar == '}') {
                ctr--;
            }
        }
        if (json.length() > 0 && ctr == 0) {
            return origBuffer;
        } 
        buf.resetReaderIndex();
        return null;
    }
}

(请原谅那些有点草率的代码 - 这是我第一次尝试使用Netty和一些学习经验。)

我看到的情况是,当我通过使用telnet连接到服务器来测试它时,这可以正常工作,粘贴一些有效的JSON并按回车键。但是,如果我在JSON字符串中的最后结束'}'之后没有按返回,则解码器永远不会被更新的缓冲区调用。

有没有办法将渠道管道配置为不同的工作方式?我已经用Google搜索并查看了Netty文档。我觉得我缺少一些基本的东西,我只是找不到合适的地方或寻找合适的东西。谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

您的telnet客户端是否恢复为“逐行旧”模式,只有完成的行发送到服务器(telnet man page)?尝试编写一个简单的Java客户端来代替发送消息。

答案 1 :(得分:1)

我想阅读JSON流更类似于读取HTTP流,因为您必须跟踪开始和结束括号(以及括号,如果JSON字符串是数组)。如果查看HTTP解码器的源代码,您将看到它正在使用ReplayingDecoder。使用重放解码器不是必需的,但如果将整个消息拆分为多个缓冲区,则会有很多帮助。

FrameDecoders用于读取由特殊字符(因此是解码器的名称)“框架”或带有长度字段的消息。

我还强烈建议使用DecoderEmbedder辅助类,以便您可以在不进行实际I / O的情况下对JSON解码器进行单元测试。