reactiveTimer
обеспечивает один подход.Я предполагаю, что ваш подход не работает, потому что observeEvent
обновляет реактивный объект только после завершения вычисления выражения.Вот мой подход.Я создаю скрипт, который хочу запустить в фоновом режиме, so_script.R
, и перенаправляю вывод в so_output.txt
.Мы хотим видеть содержимое so_output.txt
во время работы скрипта.
cat('sink(file = "so_output.txt")
for (i in 1:10) {
cat(format(Sys.time(), format = "%H:%M:%S"), "\n")
Sys.sleep(1)
}
cat("*** EOF ***\n")
sink()
', file = "so_script.R")
Вот приложение Shiny:
library(shiny)
ui <- fluidPage(
titlePanel("Stream the system output"),
sidebarLayout(
sidebarPanel(
actionButton("btn_start",label = "Let's stream"),
actionButton("btn_stop",label = "Stop")
),
mainPanel(
htmlOutput("textstream_output")
)
)
)
server <- function(input, output, session) {
rv <- reactiveValues(textstream = c(""),
timer = reactiveTimer(1000),
started = FALSE)
observeEvent(input$btn_start, {
rv$started <- TRUE
system2("Rscript", "so_script.R", wait = FALSE)
})
observeEvent(input$btn_stop, { rv$started <- FALSE })
observe({
rv$timer()
if (isolate(rv$started))
rv$textstream <- paste(readLines("so_output.txt"), collapse = "<br/>")
})
output$textstream_output <- renderUI({
HTML(rv$textstream)
})
}
shinyApp(ui = ui, server = server)
Каждый раз, когда срабатывает таймер, мы читаем содержимоеso_output.txt
, если потоковая передача началась.Выход:
![enter image description here](https://i.stack.imgur.com/Rmh02.gif)