littlejedi
littlejedi

Reputation: 989

Netty 4.0 - StringDecoder and ChannelInboundMessageHandlerAdapter<String> not working

I'm using netty 4.0.0-CR3, following the example on server-side: https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/telnet/TelnetServerPipelineFactory.java

I've constructed my pipeline as follows:

private static final StringDecoder DECODER = new StringDecoder(CharsetUtil.UTF_8);

@Override
public void initChannel(SocketChannel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();
    pipeline.addLast("decoder", DECODER);
    // and then business logic
    pipeline.addLast("serverHandler", new ServerHandler());
}

And handler:

public class ServerHandler extends ChannelInboundMessageHandlerAdapter<String> {

private static final Logger LOGGER = LoggerFactory.getLogger(ServerHandler.class);

public void messageReceived(ChannelHandlerContext ctx, String request)
        throws Exception {
    // Displays the message
    LOGGER.info("Received: " + request);
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
        throws Exception {
    LOGGER.error("Unexpected exception from downstream.", cause);
    ctx.close();
}

}

I created a simple C# client that encodes String into bytes, and send to the server. However, I don't see EITHER StringDecoder's decode() OR handler's messageReceived() called.

I then removed StringDecoder() in pipeline, and changed the handler to be:

public class Handler extends ChannelInboundByteHandlerAdapter {

@Override
protected void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in)
        throws Exception {
    System.out.println("called " + in.toString(CharsetUtil.UTF_8));

}

}

Now it works properly. Functionally both pipelines should work right? Why is the first setup not working? The client code is the same.

Thanks a lot!

Upvotes: 1

Views: 3602

Answers (2)

littlejedi
littlejedi

Reputation: 989

Thanks guys! so I added the following:

pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter()));

And this still didn't work until I explicitly add '\0' to the end to String in C# :

ASCIIEncoding encoder = new ASCIIEncoding();
int index = random.Next(0, 2);
byte[] buffer = encoder.GetBytes(list[index] + "\0");

The weird thing is that, I was using Netty 3.6 previously, and everything worked fine even without a FrameDecoder (only StringDecoder was there / client code was same) but now I have to do the steps above to make it to work..........?

Upvotes: 0

forty-two
forty-two

Reputation: 12817

The documentation for StringDecoder clearly states that it must be used in conjunction with a ByteToMessageDecoder if used over a stream connection (such as TCP). The example you refer to has such a handler in front of the StringDecoder.

Upvotes: 1

Related Questions