当netty客户端连接打开时,如何保持我的jvm退出?

时间:2012-02-01 05:23:20

标签: tcp network-programming netty

我有一个API,它使用netty打开到tcp服务器的客户端连接。服务器可以随时向客户端发送数据。我面临以下情况:

  1. 客户端连接到服务器
  2. 将数据发送到服务器
  3. 断开连接,JVM存在(不确定先发生)
  4. 这就是我的期望:

    1. 客户端连接到服务器
    2. 将数据发送到服务器
    3. 客户端只是保持连接打开,等待接收数据或客户端API用户发送数据。
    4. 这是我的连接方法的概述(显然有一个更大的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;
      }
      

      ```

2 个答案:

答案 0 :(得分:2)

这与netty无关......如果你从那里调用它,你需要确保你的“主”方法不存在。否则就是容器的工作..

答案 1 :(得分:2)

有几种方法可以做到这一点,但我观察到的一件事就是用这段代码:

ChannelFactory factory = new NioClientSocketChannelFactory(
                Executors.newCachedThreadPool(),
                Executors.newCachedThreadPool());

...如果你成功连接,你的JVM一定不会自动关闭它,直到你强制它(如杀戮)或你在你的频道工厂调用releaseExternalResources()。这是因为:

  • Executors.newCachedThreadPool()创建的主题是 nonDaemon 主题。
  • 提交连接请求后,至少会创建一个帖子。
  • 缓存的线程池线程的保持活动时间为60秒,这意味着它们在空闲60秒后不会消失,因此在连接后 60秒并发送(假设它们都已完成)。

所以我不确定你是否正确诊断了这个问题。话虽如此,我建议你这样处理任务:

  1. 使用方法启动(在主题中)
  2. 现在在新线程中启动所有您实际有用的工作。
  3. 启动有用的主题后,在主题中,调用Thread.currentThread().join()。由于 main 始终是非dameon,因此您确保JVM在您准备就绪之前不会关闭。
  4. 在某些时候,除非你希望 kill -9 将JVM作为关机策略,否则你需要一个受控制的关机,所以你可以add a shutdown hook关闭Netty然后中断线程。
  5. 我希望这有用。