情况:鉴于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
命令已经退出)。
如何整合其他执行者?我错过了一个细节吗?
答案 0 :(得分:2)
您的netty服务器按预期工作,它是echo |你正在测试的nc命令是否会提前退出。
尝试使用&#39; telnet localhost 3000&#39;对于与测试服务器的交互式会话,输入一些文本,您将看到在延迟后写入正确的响应,然后关闭该通道。
或者只需使用&#39; nc -v -w10 localhost 3000&#39;,写一些文字,按回车键,再次看到延迟和频道关闭后的预期输出。