java - 如何使用单独的任务执行器来阻止 netty 中的子任务?

标签 java multithreading netty blocking

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

这是 Netty 4!

channel 处理程序不会回显回复消息(如 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 事件循环工作组的线程。

因此,我更改了 channel 注册并应用了自定义执行器:

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() 后立即关闭。 。我可以看到任务本身将被处理,包括调用处理程序的事件方法。但相应的 channel 已经与客户端断开连接(我的 nc 命令已经退出)。

集成另一个执行器是如何工作的?我错过了一个细节吗?

最佳答案

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

尝试使用“telnet localhost 3000”与测试服务器进行交互式 session ,输入一些文本,您将看到在延迟后写入正确的响应,然后关闭 channel 。

或者只需使用“nc -v -w10 localhost 3000”,编写一些文本,按 Enter 键,您将再次在延迟和 channel 关闭后看到预期的输出。

关于java - 如何使用单独的任务执行器来阻止 netty 中的子任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23823574/

相关文章:

java - 当我必须在 Netty4 编码器中调用 ByteBuf.retain() 时?

netty - Netty 4-EventLoopGroup-EventLoop-EventExecutor-线程关联

java - bazel - netty_tcnative 错误

java - 如何删除已膨胀到屏幕的布局

java - 框/表内的输入框

java - 如何在没有任何外部依赖的情况下从 java 应用程序调用 php Web 服务?

c# - 异步 - 等待两个异步任务完成

Java——对象的创建和可见性

c++ - C++ 的双重检查锁是否有任何潜在问题?

java - 如何解析键名是整数的json