2016-06-09 6 views
2

Beispiel https://github.com/spring-projects/spring-integration-samples/tree/master/basic/tcp-client-server ist großartig, um eine TCP-Server-Anwendung zu erstellen. Es ist einfach und läuft auf JVM. Es benötigt keinen Anwendungsserver.So führen Sie den TCP-Server aus, bis er gestoppt wird

Beispiel verwendet Befehlszeileneingabe, um das Programm auszuführen. Ich möchte, dass der Server Daten nur vom Socket-Port und nicht über die Befehlszeile akzeptiert. Wenn ich die Eingabe der Befehlszeile entferne, wird der Haupt-Thread beendet und das Programm akzeptiert keine Eingabe mehr vom Port. Ich muss den Hauptfaden die ganze Zeit laufen lassen.

ich einige etwas wie dieses denke:

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

Ich habe zwei Fragen:

  1. ist es eine saubere Art und Weise weiterhin der Haupt-Thread laufen zu machen?

  2. Woher weiß man, dass das Gateway gestoppt ist? Wenn der Benutzer TCP-Daten als "Quit" sendet, kann das Gateway gestoppt werden. Gibt es eine Möglichkeit zu wissen, dass Gateway gestoppt ist?

Dank

Antwort

1

Eine andere Lösung ist wie folgt:

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(); 
} 

Sie die ApplicationContext starten und für den Anschlag von der Konsole Eingang warten.

EDIT

Für den Fall, wenn Sie möchten Programm über ein Ereignis in der Anwendung zu stoppen, Sie ApplicationListener und warten auf die Barriere vor bestehenden vom main registrieren:

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

Jetzt sollten Sie nur eine Logik in Ihrer Anwendung finden, um dort ctx.stop() anzurufen.

+0

Ich möchte keine Eingabe von der Befehlszeile nehmen, weil es ein Server ist. Gibt es im Frühjahr ein Dienstprogramm, das den Daemon-Thread starten und den Status des Gateways abfragen kann? – kevin

+0

Sehen Sie ein EDIT in meiner Antwort. –

+0

Das ist perfekt Artem. schnelle Frage: Siehe https://github.com/spring-projects/spring-integration-samples/tree/master/intermediate/monitoring für die Verwendung von Control-Channel. Nachricht operation = MessageBuilder.withPayload ("@ integrationMBeanExporter.stopActiveComponents (false, 20000)"). Build(); if (this.exporter! = Null) { \t this.controlBusChannel.send (Operation); } Wenn ich stopActiveComponents() über den Steuerkanal sende, wird ContextClosedEvent gesendet? – kevin

1

Sie können wait() auf dem Gateway-Thread aus dem Hauptthread rufen Sie den Haupt-Thread warten, bis Gateway-Thread beendet zu machen. Sie müssen notify() vom Gateway-Thread (wenn es anhalten sollte) aufrufen, um anzuzeigen, dass es fertig ist und warten, dass Threads weiterlaufen sollen (in diesem Fall wird main ausgeführt und beendet). Ein Beispiel kann found here sein.

Oder (eine andere Lösung für eine sehr einfache Anwendung), können Sie versuchen, so etwas wie folgenden Daten aus einem Hauptverfahren zu lesen und das Programm zu stoppen, wenn die Daten auf einen Befehl gleich lesen, das Programm zu stoppen:

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

Das Lesen der Socketdaten erfolgt über die Federintegration, daher kann System.exit() nicht aufgerufen werden. Die Spring-Integration hat bereits einen Port zum Lesen von Daten geöffnet. Ich möchte nicht einen anderen Port wie 9000 öffnen, nur um das System zu schließen. – kevin