2017-10-19 5 views
0

J'ai une application brillante qui fait un appel système en commençant un deuxième processus, dans ce cas un programme C++ (pour diverses raisons Rcpp n'est pas une option pour ce projet). Le programme C++ prend un certain temps à s'exécuter mais donne un retour d'information continu (comme quelques fois par seconde) au terminal.Appel système brillant avec mises à jour continues

Je peux exécuter le programme à partir de l'application brillante et récupérer la sortie de l'appel système, mais il attend jusqu'à ce que le processus est terminé. Maintenant, ma question est, y at-il un moyen de mettre à jour en continu le texte à l'intérieur de l'application brillante?

À titre d'exemple, je l'application brillante suivante

ui <- bootstrapPage(
    verbatimTextOutput("text") 
) 

server <- function(input, output) { 
    a <- system("./tmp", intern = T, wait = F) 
    output$text <- renderText(paste(a, collapse = "\n")) 
} 

shinyApp(ui = ui, server = server) 

et c suivant ++ code (dans tmp.cpp compilé avec g++ tmp.cpp -o tmp)

#include <unistd.h> 
#include <stdio.h> 

int main() { 
    for (int i = 0; i < 10; ++i) { 
     printf("i is now %i\n", i); // print the current state 
     fflush(stdout);    // force the print 
     usleep(1000000);   // sleep for one second 
    } 
    return 0; 
} 

Après avoir attendu les dix secondes, la sortie s'affiche , je veux que chaque étape soit montrée.

Des idées/solutions à cela? Merci beaucoup!

+1

Vous pouvez enregistrer votre sortie C++ sous forme de fichier texte et lire ce fichier de manière "réactive". Voir ma réponse [ici] (https://stackoverflow.com/questions/46719268/shiny-app-does-not-reflect-changes-in-update-rdata-file/46747407#46747407) (Option 4). –

+0

Cela semble parfait, si vous écrivez une réponse courte, je serai volontiers upvote et l'accepter. – David

Répondre

1

Comme suggéré dans les commentaires, je préconise une connexion entre C++ et brillant via un fichier texte. Ma réponse here vous montre comment importer un fichier "de manière réactive". Ce qui suit est adapté de l'option 4 dans la réponse liée.

Notez que le processus démarrera une fois pour chaque utilisateur qui se connecte. Vous pouvez donc modifier ce code en déplaçant la ligne system("./tmp > mytext.txt", intern = F, wait = FALSE) dans global.R.

ui <- bootstrapPage( 
    verbatimTextOutput("text") 
) 

server <- function(input, output, session) { 

    system("./tmp > mytext.txt", intern = F, wait = FALSE) 

    observe({ 
    ## read the text file once every 50 ms 
    invalidateLater(50, session) 
    req(file.exists("mytext.txt")) 
    txt <- paste(readLines("mytext.txt"), collapse = "\n") 
    output$text <- renderText(txt) 
    }) 
} 

shinyApp(ui = ui, server = server)