2016-11-24 1 views
0

J'ai un processus ProcessBuilder exécuté avec succès qui scanne un DVB-T pour les diffusions de chaînes sur un serveur et je veux que la sortie se passe sur une page Web.Java ProcessBuilder comment récupérer la sortie en direct

Le code du serveur comme suit:

private static StringBuilder scan_output = null; 
private static String scan_result = ""; 

@Override 
public boolean scanByBroadcaster(String user, String broadcaster) { 
    UserAccountPermissions perm = validateUserEdit(user); // allowed to run scan? 
    if (perm == null) return false; 

    String[] commands = { 
      "/usr/bin/scan", 
      dvbDir + broadcaster, 
      "-o", 
      "zap", 
      "-U", 
      "-q", 
      "-a", 
      "5", 
      ">", 
      LoginConstants.loc_dvb_scanfile 
    }; 

    System.out.println("Scan by broadcast: " + broadcaster); 

    scan_output = new StringBuilder(); 
    new ScanThread(commands).start(); 

    return false; 
} 

// runs the scan independant and the IO capture 
private static class ScanThread extends Thread { 
    String[] commands = null; 
    public ScanThread(String[] commands) { 
     this.commands = commands; 
    } 
    public void run() { 
     ProcessBuilder pb = new ProcessBuilder(commands); 
     Process process; 
     try { 
      System.out.println("Scan thread running"); 
      process = pb.start(); 
      IOScanOutputHandler handler = new IOScanOutputHandler(process.getInputStream()); 
      handler.start(); 
      process.waitFor(); 
     } catch (IOException e) { 
      System.out.println(e.getMessage()); 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      System.out.println(e.getMessage()); 
      e.printStackTrace(); 
     } 
     //scan_output = null; 
     System.out.println("Scan thread finished"); 
    } 
} 

// background thread to capture output of scan (as it arrives) 
// this only captures the final scan results though 
private static class IOScanOutputHandler extends Thread { 
    private InputStream inputStream; 

    IOScanOutputHandler(InputStream inputStream) { 
     this.inputStream = inputStream; 
    } 

    public void run() { 
     Scanner br = null; 
     try { 
      System.out.println("Scan thread IO capture running"); 
      br = new Scanner(new InputStreamReader(inputStream)); 
      String line = null; 
      while (br.hasNextLine()) { 
       line = br.nextLine(); 
       scan_output.append(line + System.getProperty("line.separator")); 
      } 
     } finally { 
      br.close(); 
     } 
     System.out.println("Scan thread IO capture finished"); 
     scan_result = scan_output.toString(); 
     scan_output = null; 
    } 
} 

// polled by web interface every second 
@Override 
public String pollScanResult(String user) { 
    if (validateUserEdit(user) == null) return null; 
    StringBuilder sb = scan_output; // grab instance 
    if (sb == null) return null; 
    return sb.toString(); 
} 

La sortie finale, je reçois en fait est ce qui se passe dans « LoginConstants.loc_dvb_scanfile » et non cette sortie:

ERROR: invalid enum value '7378' 
ERROR: invalid enum value '3300' 
ERROR: invalid enum value '0' 
ERROR: invalid enum value '8MHz' 
ERROR: invalid enum value '2/3' 
ERROR: invalid enum value 'NONE' 
ERROR: invalid enum value 'QAM2' 
>>> tune to: 706000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE 
>>> tune to: 778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE 
>>> tune to: 2:INVERSION_AUTO:BANDWIDTH_AUTO:FEC_AUTO:FEC_AUTO:QAM_AUTO:TRANSMISSION_MODE_AUTO:GUARD_INTERVAL_AUTO:HIERARCHY_AUTO 
__tune_to_transponder:1910: ERROR: Setting frontend parameters failed: 22 Invalid argument 
>>> tune to: 2:INVERSION_AUTO:BANDWIDTH_AUTO:FEC_AUTO:FEC_AUTO:QAM_AUTO:TRANSMISSION_MODE_AUTO:GUARD_INTERVAL_AUTO:HIERARCHY_AUTO 
__tune_to_transponder:1910: ERROR: Setting frontend parameters failed: 22 Invalid argument 
>>> tune to: 770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE 
>>> tune to: 698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE 
>>> tune to: 746000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE 
>>> tune to: 762000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE 
WARNING: filter timeout pid 0x0011 
WARNING: filter timeout pid 0x0000 
WARNING: filter timeout pid 0x0010 

L'analyse est commencé à partir GWT côté client via des appels RPC. Par souci de concision, voici ce code:

private void runScanQuick() { 
    server.checkEditAccess(user, new AsyncCallback<Boolean>() { 

     @Override 
     public void onFailure(Throwable caught) { 
      log.info("runScanQuick server failure"); 
     } 

     @Override 
     public void onSuccess(Boolean result) { 
      if (result == false) return; // not allowed to run scan 

      final DialogBox dia = new DialogBox(); 
      final Frame frame = new Frame(url_base + url_ext_scanbybroadcaster); 
      frame.addLoadHandler(new LoadHandler() { 

       @Override 
       public void onLoad(LoadEvent event) { 
        String broadcaster = scan_country.getSelectedItemText() + "-" + scan_broadcaster.getSelectedItemText(); 
        log.info("Scan file: " + broadcaster); 
        Document doc = IFrameElement.as(frame.getElement()).getContentDocument(); 
        doc.getElementById("broadcaster").appendChild(new HTML(broadcaster).getElement()); 
        Button okay = Button.wrap(doc.getElementById("okay")); 
        Button cancel = Button.wrap(doc.getElementById("cancel")); 
        cancel.addClickHandler(new ClickHandler() { 

         @Override 
         public void onClick(ClickEvent event) { 
          dia.hide(); 
         } 
        }); 
        okay.addClickHandler(new ClickHandler() { 

         @Override 
         public void onClick(ClickEvent event) { 
          dia.hide(); 
          runScanQuickStart(); 
         } 
        }); 
       } 
      }); 
      frame.setSize("500px", "500px"); 
      dia.add(frame); 
      dia.setGlassEnabled(true); 
      dia.setStyleName(""); 
      dia.center(); 
      dia.show(); 
     } 
    }); 
} 

private void runScanQuickStart() { 
    final DialogBox dia = new DialogBox(); 
    final Frame frame = new Frame(url_base + url_ext_scanbroadcasterprogress); 
    frame.addLoadHandler(new LoadHandler() { 

     @Override 
     public void onLoad(LoadEvent event) { 
      Document doc = IFrameElement.as(frame.getElement()).getContentDocument(); 
      String broadcaster = scan_country.getSelectedItemText() + "-" + scan_broadcaster.getSelectedItemText(); 
      doc.getElementById("title").appendChild(new HTML(broadcaster).getElement()); 
      Button okay = Button.wrap(doc.getElementById("okay")); 
      final TextArea area = TextArea.wrap(doc.getElementById("textarea")); 
      final Timer timer = new Timer() { 
       @Override 
       public void run() { 
        server.pollScanResult(user, new AsyncCallback<String>() { 

         @Override 
         public void onFailure(Throwable caught) { 
          cancel(); 
         } 

         @Override 
         public void onSuccess(String result) { 
          if (result == null) cancel(); 
          else { 
           area.setText(result); 
          } 
          log.info("Polled for scan result"); 
         } 
        }); 
       } 
      }; 
      okay.addClickHandler(new ClickHandler() { 

       @Override 
       public void onClick(ClickEvent event) { 
        timer.cancel(); 
        dia.hide(); 
       } 
      }); 
      server.scanByBroadcaster(user, broadcaster, new AsyncCallback<Boolean>() { 

       @Override 
       public void onFailure(Throwable caught) { 
        log.info("runScanQuickStart server call failed"); 
       } 

       @Override 
       public void onSuccess(Boolean result) { 
        if (result == false) return; 
        timer.scheduleRepeating(1000); 
       } 
      }); 
     } 
    }); 
    frame.setSize("740px", "500px"); 
    dia.add(frame); 
    dia.setGlassEnabled(true); 
    dia.setStyleName(""); 
    dia.center(); 
    dia.show(); 
} 

Tout fonctionne très bien en dehors du fait que je ne sais pas comment récupérer la sortie en direct du ProcessBuilder.

Est-ce que quelqu'un sait comment saisir la sortie en direct pour que je puisse afficher des commentaires en direct sur la page Web? Je pense que peut-être que ce pourrait être soit stderr, stdout ou quelque chose.

Répondre

0

Après deux jours de lutte avec cela et après avoir posté une question, je l'ai compris une demi-heure plus tard. Grr ...

j'ai changé cette plus pour obtenir le flux d'erreur:

//IOScanOutputHandler handler = new IOScanOutputHandler(process.getInputStream()); 
IOScanOutputHandler handler = new IOScanOutputHandler(process.getErrorStream()); 

Et dans le, je viens d'ajouter le retour fonction serveur scanByBroadcaster() vrai qui a permis la minuterie côté client pour commencer l'interrogation.

Ouf !!!