How to properly handle decoder chain in netty?

Jiang Bian timobj at gmail.com
Tue Jun 2 19:20:16 EDT 2009


I am just wondering whether I am doing the right thing. Don't want to walk on
the wrong path too far...

I am doing a customized binary protocol. Here is my pipeline factory

@Override
    public ChannelPipeline getPipeline() throws Exception {
	ChannelPipeline p = pipeline();
	p.addLast("logger", new LoggingHandler(true));
	p.addLast("jigdfsDecoder", new JigDFSCommandDecoder());
	p.addLast("chunkDecoder", new FileChunkDecoder());
        p.addLast("handler", new NodeServerHandler(this.node));
        return p;
    }

As you might have guessed, every message in my system starts with a magic
number, followed by another integer indicates the command. So I have a
JigDFSCommandDecoder() (extends OneToOneDecoder) upfront to make sure every
message is generated by my protocol. 

I am also sending large files across the network. So I have a
FileChunkDecoder (extends FrameDecoder) to decoder the ChannelBuffer to a
Chunk object. It also do some other crazy things, verifying md5, tracking
segment index, etc., so I didn't used LengthBasedFrameDecoder directly.

Here comes the question: In the JigDFSCommandDecoder, I still return the
Channel, and set the context attachment to be the JigDFSCommand.

@Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel,
	    Object msg) throws Exception {
	if (!(msg instanceof ChannelBuffer)) {
	    return msg;
	} else {
	    ChannelBuffer buffer = (ChannelBuffer) msg;

	    if (buffer.readableBytes() < 8) {
		return null;
	    }

	    int magicNumber = buffer.readInt();
	    if (magicNumber != JigDFSCommand.JIGDFS_MAGIC_NUMBER) {
		logger.info("It's not a JigDFS message! magic number: "
			+ magicNumber);
		logger.info(buffer.toString());
		System.exit(-1);
		return 0;
	    }

	    int command = buffer.readInt();
	    
	    ctx.setAttachment(new JigDFSCommand(command));
	    return buffer;
	}

    }

Then in the FileChunkDecoder, I am checking to see if it's ChunkData
command. 

@Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel,
	    ChannelBuffer buffer) throws Exception {
	
	if(!(ctx.getAttachment() instanceof JigDFSCommand)){
	    return null;
	}
	
	JigDFSCommand cmd = (JigDFSCommand) ctx.getAttachment();
	
	if(cmd.getJigDFSCommand() != JigDFSCommand.CHUNK_DATA){
	    return null;
	}
	
	// Make sure if the segment, md5 & length fields were received.
	if (buffer.readableBytes() < 24) {
		// The length field was not received yet - return null.
		// This method will be invoked again when more packets are
		// received and appended to the buffer.
		return null;
	}

... the rest is irrelevant...

}

Am I doing the right thing? Or is there a better/correct way to do this?

Thanks a bunch in advance,

Jiang


 
-- 
View this message in context: http://n2.nabble.com/How-to-properly-handle-decoder-chain-in-netty--tp3015408p3015408.html
Sent from the Netty User Group mailing list archive at Nabble.com.




More information about the netty-users mailing list