我有一个API,它使用netty打开客户端与tcp服务器的连接。服务器可以在任何时间向客户端发送数据。我面临以下情况:
- 客户端连接到服务器
- 将数据发送到服务器
- 断开连接并且JVM存在(不确定是否首先发生)
这就是我所期望的:
- 客户端连接到服务器
- 将数据发送到服务器
- 客户端只是保持连接处于打开状态,等待接收数据或等待客户端API的用户发送数据
这是我的连接方法的概述(显然有一个更大的API围绕它):
```
public FIXClient connect(String host, int port) throws Throwable {
...
ChannelPipeline pipe = org.jboss.netty.channel.Channels.pipeline(...);
ChannelFactory factory = new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
ClientBootstrap bootstrap = new ClientBootstrap(factory);
bootstrap.setPipeline(pipe);
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("keepAlive", true);
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
//forcing the connect call to block
//don't want clients to deal with async connect calls
future.awaitUninterruptibly();
if(future.isSuccess()){
this.channel = future.getChannel();
//channel.getCloseFuture();//TODO notifies whenever channel closes
}
else{
throw future.getCause();//wrap this in a more specific exception
}
return this;
}
```
这与netty无关。。。如果从那里调用"main"方法,则需要确保该方法不存在。否则就是容器的工作。。
有几种方法可以做到这一点,但我观察到的一件事是,使用以下代码:
ChannelFactory factory = new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
如果连接成功,JVM在一段时间内不会自动关闭,直到您强制它(像kill一样)或在通道工厂上调用releaseExternalResources()。这是因为:
- executor.newCachedThreadPool()创建的线程是非守护进程线程
- 提交连接请求后,至少会创建1个线程
- 缓存的线程池线程的保持活动时间为60秒,这意味着它们在空闲60秒之前不会消失,因此这将是连接和发送后的60秒(假设它们都完成了)
所以我不确定你是否正确诊断了这个问题。话虽如此,我建议你这样处理任务:
- 在main方法中启动后(在main
- 现在启动所有您在新线程中实际有用的工作
- 一旦启动了有用的线程,在main线程中,调用thread.currentThread().join()。由于main总是非dameon,所以您已经确保JVM在准备好之前不会关闭
- 在某种程度上,除非希望杀死-9
JVM作为关闭策略,否则您将希望受控关闭,因此您可以添加一个关闭挂钩来关闭Netty,然后中断main线程
我希望这会有所帮助。