如何使用单独的任务执行程序来阻止netty中的子任务?

时间:2014-05-23 07:38:16

标签: java multithreading netty blocking

情况:鉴于telnet客户端&官方仓库(https://github.com/netty/netty/tree/4.0/example/src/main/java/io/netty/example/telnet)的服务器示例,我使用虚假阻止任务对此进行了一些更改:https://github.com/knalli/netty-with-bio-task/tree/master/src/main/java/de/knallisworld/poc

这是Netty 4!

而不是echo回复消息(就像telnet服务器演示一样),通道处理程序阻塞线程一段时间(在现实世界中使用JDBC或JSch等......)。

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

这实际上有效:我用echo "Hello" | nc localhost $port)对此进行测试,线程将被阻止(并且nc等待),直到3秒后返回。

但是,这意味着我阻止了Netty事件循环工作组的一个线程与一个不相关的任务。

因此,我改变了频道注册并应用了自定义执行者:

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);
    }
}

不幸的是,在此配置之后,套接字将在退出处理程序channelRead0()后立即关闭。我可以看到任务本身将被处理,包括调用处理程序的事件方法。但是相应的通道已经与客户端断开连接(我的nc命令已经退出)。

如何整合其他执行者?我错过了一个细节吗?

1 个答案:

答案 0 :(得分:2)

您的netty服务器按预期工作,它是echo |你正在测试的nc命令是否会提前退出。

尝试使用&#39; telnet localhost 3000&#39;对于与测试服务器的交互式会话,输入一些文本,您将看到在延迟后写入正确的响应,然后关闭该通道。

或者只需使用&#39; nc -v -w10 localhost 3000&#39;,写一些文字,按回车键,再次看到延迟和频道关闭后的预期输出。