Java 如何使用单独的任务执行器来阻止netty中的子任务?
情境:考虑到官方repo()的telnet客户机和服务器示例,我使用了一个伪阻塞任务对其进行了一些更改: 这是Netty 4 通道处理程序不再像telnet服务器演示那样回显回复消息,而是在一段时间内阻塞线程(在现实世界中使用JDBC或JSch等东西) 这实际上是可行的:我正在用一个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事件循环工作组的线程 因此,我更改了频道注册并应用
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);
}
}