LengthFieldBasedFrameDecoder移除ChannelHandler,但仍会在下一个事件中调用

时间:2012-09-13 04:47:16

标签: netty

我正在尝试处理以下消息:

CMD (string) FLAG (byte) CMD_OPT (string)

字符串由包含长度的单个前导字节表示,后跟最多255个字节。所以对于一个具体的例子:

 EQ_REGISTER 0 flaux

有19个字节。在我的管道中,我从一个LengthFieldBasedFrameDecoder开始,然后一旦我确认第一个字符串的值,我尝试删除第一个解码器。问题是,解码器在FLAG字节上再次被调用,我的逻辑关闭。

这是我的管道:

    ChannelPipeline pipeline = Channels.pipeline();

    pipeline.addLast("commandDecoder", new CerbStringDecoder());
    pipeline.addLast("commandHandler", new EventQueueCmdServerHandler());

CerbStringDecoder是这样的:

   class CerbStringDecoder extends LengthFieldBasedFrameDecoder {
    public CerbStringDecoder() {
        super(255, 0, 1, 0, 1);
    }


    protected Object decode(
            ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
        ChannelBuffer buf = (ChannelBuffer) super.decode(ctx, channel, buffer);

        if (buf == null)
            return null;

        return buf.toString(Charset.forName("UTF-8"));
    }
}


 public class EventQueueCmdServerHandler extends SimpleChannelHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {

        String command = (String) e.getMessage();

        if (EQ_REGISTER.equals(command)) {
            System.out.println("COMMAND: [" + command + "]");
            ctx.getPipeline().addLast("handler", new EventQueueRegisterHandler());
            ctx.getPipeline().remove("commandDecoder");

       ....

EventQueueRegisterHandler期望获取FLAG和CMD_OPT等。

关于我做错了什么的建议,或者这是否是Netty中的错误/限制?

由于

1 个答案:

答案 0 :(得分:1)

您需要使用“replace(..)”方法以确保在删除时刷新所有缓冲的字节。请参阅javadocs [1]。

[1] http://static.netty.io/3.5/api/org/jboss/netty/handler/codec/frame/FrameDecoder.html#replace(java.lang.String,%20org.jboss.netty.channel.ChannelHandler