2016-06-09 81 views
2

示例https://github.com/spring-projects/spring-integration-samples/tree/master/basic/tcp-client-server非常適合構建TCP服務器應用程序。它很簡單,可以在JVM上運行。它不需要任何應用程序服務器。如何使TCP服務器運行直至停止

示例使用命令行輸入來運行程序。我希望服務器只接受來自Socket端口的數據,而不是通過命令行。如果我刪除命令行輸入,則主線程正在完成,程序不再接受來自端口的輸入。我必須始終保持主線程運行。

我想有些事情是這樣的:

boolean isGatewayStopped = false; 
    while (!isGatewayStopped) { 
     try { 
      Thread.sleep(5000); 
      isGatewayStopped = getGatewayStatus(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

我有兩個問題:

  1. 有使主線程繼續運行的一個乾淨的方式?

  2. 如何知道網關已停止?如果用戶以「退出」方式發送TCP數據,則可以停止網關。有什麼方法可以知道網關已停止嗎?

感謝

回答

1

另一種解決方案是這樣的:

public static void main(String[] args) throws Exception { 
     ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args); 
     System.out.println("Hit 'Enter' to terminate"); 
     System.in.read(); 
     ctx.close(); 
} 

啓動ApplicationContext並等待來自控制檯輸入停止。

編輯

因爲當你想通過應用程序中的事件從main現有之前停止程序,你可以註冊ApplicationListener並等待障礙的情況下:

CountDownLatch exitLatch = new CountDownLatch(1); 
ctx.addApplicationListener(ContextClosedEvent e -> exitLatch.countDown()) 
exitLatch.await(); 

現在你應該在應用程序中想出一些邏輯來在那裏調用ctx.stop()

+0

我不想從命令行輸入數據,因爲它是一臺服務器。春天有什麼實用程序可以啓動守護程序線程並查詢網關的狀態嗎? – kevin

+0

在我的答案中查看編輯。 –

+0

這就是完美的阿爾喬姆。快速問題: 有關使用控制通道,請參閱https://github.com/spring-projects/spring-integration-samples/tree/master/intermediate/monitoring。 消息 operation = MessageBuilder.withPayload(「@ integrationMBeanExporter.stopActiveComponents(false,20000)」)。build();如果(this.exporter!= null){ } this.controlBusChannel.send(operation); } 如果我發送stopActiveComponents()使用控制通道,它會發送ContextClosedEvent? – kevin

1

你可以調用wait()網關線程從主線程使主線程等待,直到網關線程結束。你需要從網關線程(當它應該停止)調用notify()來指示它已完成,並且等待線程應該繼續運行(在這種情況下,main將運行並退出)。一個例子可以是found here

不然(一個非常簡單的應用程序不同的解決方案),你可以嘗試像下面從主方法來讀取數據,並在數據讀取等於命令停止程序停止程序:

class Server 
{ 
    static Executor pool = Executors.newFixedThreadPool(5); 

    public static void main(String[] args) throws IOException 
    { 
     ServerSocket serverSocket = new ServerSocket(9000); 
     while (true) 
     { 
     final Socket s = serverSocket.accept(); 
     Runnable r = new Runnable() 
         { 
         @Override 
         public void run() 
         { 
          // read data from socket 's' here 
          // call System.exit() if command is to stop. 
         } 
         }; 
     pool.execute(r); 
     } 
    } 
+0

讀取套接字數據由spring集成處理,因此System.exit()不能被調用。 Spring集成已經有一個端口可以讀取數據。我不想打開另一個像9000這樣的端口來關閉系統。 – kevin