2
votes

Situation: Given the telnet client & server example of the official repo (https://github.com/netty/netty/tree/4.0/example/src/main/java/io/netty/example/telnet), I've change this a little bit using a fake blocking task: https://github.com/knalli/netty-with-bio-task/tree/master/src/main/java/de/knallisworld/poc

This is Netty 4!

Instead of echo replying the message (like the telnet server demo does), the channel handler blocks the thread for some time (in real world with things like JDBC or JSch, ...).

try { Thread.sleep(3000); } catch (InterruptedException e) {};
future = ctx.write("Task finished at " + new Date());
future.addListener(ChannelFutureListener.CLOSE);

This actually works: I'm testing this with a echo "Hello" | nc localhost $port) and the thread will be blocked (and nc waits) until it returns 3 seconds later.

However, this means I'm blocking a thread of Netty's event loop worker group with an unrelated task.

Therefor, I've changed the channel registration and applied a custom executor:

public class TelnetServerInitializer extends ChannelInitializer<SocketChannel> {

    private static final StringDecoder DECODER = new StringDecoder();
    private static final StringEncoder ENCODER = new StringEncoder();

    private TelnetServerHandler serverHandler;
    private EventExecutorGroup executorGroup;

    public TelnetServerInitializer() {
        executorGroup = new DefaultEventExecutorGroup(10);
        serverHandler = new TelnetServerHandler();
    }

    @Override
    protected void initChannel(final SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

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

        pipeline.addLast("decoder", DECODER);
        pipeline.addLast("encoder", ENCODER);

        // THIS!
        pipeline.addLast(executorGroup, "handler", serverHandler);
    }
}

Unfortunately, after this configuration the socket will be closed immediately after exiting handler's channelRead0(). I can see that the task itself will be processed including calling the handler's event methods. But the corresponding channel is already disconnected to the client (my nc command as already exited).

How does integrating another executor work? Am I missing a detail?

1

1 Answers

2
votes

Your netty server is working as expected, it's the echo | nc command you are testing with that is exiting early.

Try using 'telnet localhost 3000' for an interactive session with your test server, enter some text and you'll see that the correct response is written after a delay, then the channel is closed.

Or just use 'nc -v -w10 localhost 3000', write some text, hit enter, again you'll see the expected output after a delay and the channel closed.