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

Java 如何使用单独的任务执行器来阻止netty中的子任务?,java,multithreading,netty,blocking,Java,Multithreading,Netty,Blocking,情境:考虑到官方repo()的telnet客户机和服务器示例,我使用了一个伪阻塞任务对其进行了一些更改: 这是Netty 4 通道处理程序不再像telnet服务器演示那样回显回复消息,而是在一段时间内阻塞线程(在现实世界中使用JDBC或JSch等东西) 这实际上是可行的:我正在用一个echo“Hello”| nc localhost$port)测试它,线程将被阻塞(并且nc等待),直到3秒后返回 然而,这意味着我正在用一个无关的任务阻塞Netty事件循环工作组的线程 因此,我更改了频道注册并应用

情境:考虑到官方repo()的telnet客户机和服务器示例,我使用了一个伪阻塞任务对其进行了一些更改:

这是Netty 4

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

这实际上是可行的:我正在用一个
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);
    }
}
公共类TelnetServerInitializer扩展了ChannelInitializer{
私有静态最终StringDecoder解码器=新StringDecoder();
私有静态最终StringEncoder编码器=新StringEncoder();
私有TelnetServerHandler;
私人事件执行组执行组;
公共TelnetServerInitializer(){
executorGroup=新的DefaultEventExecutorGroup(10);
serverHandler=新的TelnetServerHandler();
}
@凌驾
受保护的void initChannel(最终SocketChannel ch)引发异常{
ChannelPipeline=通道管道();
pipeline.addLast(“framer”,新的DelimiterBasedFrameDecoder(
8192,Delimiters.lineDelimiter());
pipeline.addLast(“解码器”,解码器);
pipeline.addLast(“编码器”,编码器);
//这个!
addLast(executorGroup,“handler”,serverHandler);
}
}
不幸的是,在此配置之后,套接字将在退出处理程序的
channelRead0()
后立即关闭。我可以看到任务本身将被处理,包括调用处理程序的事件方法。但相应的通道已断开与客户端的连接(我的
nc
命令已退出)


集成另一个执行器如何工作?我遗漏了一个细节吗?

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

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


或者只需使用“nc-v-w10localhost 3000”,编写一些文本,点击回车键,在延迟和通道关闭后,您将再次看到预期的输出。

@knalli还将writeAndFlush添加到call方法中的BlockingCall return语句中以查看消息,或者使用ChannelFutureListener->operationComplete->ctx.flushTelnetServerHandler@derek:嗯。感谢您向我展示了真正的问题(nc)。然而,关于nc超时的最后一点并没有任何区别(我已经检查过了,但没有提到)。Telnet显示了它的工作原理。现在我正在寻找一个支持bash/脚本的解决方案。@jknair:也谢谢你。你是对的,那会更好,但在这种情况下,这并不是真的必要。
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);
    }
}