0

我正在使用 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 字符串中的最后一个关闭“}”之后不按返回,则解码器永远不会被更新的缓冲区调用。

有没有办法配置通道管道以不同的方式工作?我已经用谷歌搜索了这个并查看了 Netty 文档。我觉得我错过了一些基本的东西,我只是没有在正确的地方寻找或寻找正确的东西。谢谢你的帮助。

4

2 回答 2

1

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

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

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

于 2013-03-23T12:59:09.250 回答
1

您的 telnet 客户端是否恢复到“旧的逐行”模式,即只将完整的行发送到服务器(telnet 手册页)?尝试编写一个简单的 Java 客户端来发送消息。

于 2013-03-23T12:50:49.640 回答