我正在使用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文档。我觉得我缺少一些基本的东西,我只是找不到合适的地方或寻找合适的东西。谢谢你的帮助。
答案 0 :(得分:1)
您的telnet客户端是否恢复为“逐行旧”模式,只有完成的行发送到服务器(telnet man page)?尝试编写一个简单的Java客户端来代替发送消息。
答案 1 :(得分:1)
我想阅读JSON流更类似于读取HTTP流,因为您必须跟踪开始和结束括号(以及括号,如果JSON字符串是数组)。如果查看HTTP解码器的源代码,您将看到它正在使用ReplayingDecoder。使用重放解码器不是必需的,但如果将整个消息拆分为多个缓冲区,则会有很多帮助。
FrameDecoders用于读取由特殊字符(因此是解码器的名称)“框架”或带有长度字段的消息。
我还强烈建议使用DecoderEmbedder辅助类,以便您可以在不进行实际I / O的情况下对JSON解码器进行单元测试。