RStudio Server on linux: how to create a shiny app that immediately returns user input text if button OK pressed, or FALSE if button CANCEL pressed

Viewed 264

I want my function to implement a dialog with an editable text box using a shiny app.

I.e. calling the function should open a shiny app displaying some text for the user to edit, then press the 'Ok' button to close the app and return the edited text or the 'Cancel' button to close the app and return an empty character vector.

My code runs fine on Windows (Rstudio desktop). However on Linux (Rstudio Server Pro) the shiny page is displayed but the interface seems to be greyed, the text can be edited but the buttons are not responsive. Why?

--EDIT--

The unresponsiveness problem occurs with Internet Explorer and Microsoft Edge, not Chrome. Although the page in Chrome is greyed too, and opening Chrome's 'Inspect' tool shows 2 errors:

(1) shinyapp.js:83 WebSocket connection to 'wss://XXXXXXXXXXXXXXX/websocket/' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
(2) Uncaught TypeError: Cannot read property 'readyState' of null
    at ShinyApp.$sendMsg (shiny.min.js:3)
    at ShinyApp.sendInput (shiny.min.js:3)
    at InputBatchSender.$sendNow (shiny.min.js:3)

[where XXXXXXXXXXXXXXX stands for my Rstudio Server's URL]

library(shiny)


getMyText <- function(default = "This is my input\n- Anonymous") {
  require(stringr)
  ui <- fluidPage(
    textAreaInput("myTextBox", "Edit text", paste(default, collapse="\n"),
                  width = "600px", height = "400px"),
    actionButton("okBtn", "Ok"),
    actionButton("cancelBtn", "Cancel")
  )
  server <- function(input, output) {
    observe({
      if(input$cancelBtn > 0){
        stopApp(character(0))
      }
    });
    observe({
      if(input$okBtn > 0){
        stopApp(unlist(str_split(input$myTextBox, "\n")))
      } 
    });
  }
  return(runApp(list(ui = ui, server = server)))
}
args <- getMyText()

sessionInfo:


sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: Red Hat Enterprise Linux Server 7.4 (Maipo)

Matrix products: default
BLAS/LAPACK: /usr/lib64/R/lib/libRblas.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8   
 [6] LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] stringr_1.3.1 shiny_1.4.0.2

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4      digest_0.6.18   later_1.0.0     mime_0.6        R6_2.4.1        xtable_1.8-3    magrittr_1.5    rlang_0.4.5    
 [9] stringi_1.1.7   promises_1.1.0  tools_3.5.0     httpuv_1.5.2    yaml_2.2.0      fastmap_1.0.1   compiler_3.5.0  htmltools_0.4.0
> 
2 Answers

The greyed out screen to me sounds like your observe block is firing before all inputs are set up. This can be remedied in two ways:

observe({
  req(input$cancelBtn)
  if (input$cancelBtn > 0) {
    stopApp(character(0))
  }
})
observeEvent(input$cancelBtn, {
  if (input$cancelBtn > 0) {
    stopApp(character(0))
  }
}, ignoreNULL = TRUE)     # which is the default, including it for clarity

FYI: win10, R-3.5.3, shiny-1.4.0

It turns out this problem was due to a server (mis)configuration. Interestingly, I found out that setting option shiny.host to the IP address of the server (instead of the default 127.0.0.1) enabled interaction with the shiny app, e.g.:

options(shiny.host = '10.1.2.3')

The following code could be used to set this option dynamically on a Linux host, useful in case load balancing gets the user connected to one of several Rstudio servers:

if (Sys.info()["sysname"] == 'Linux') {
  hostIP <- system("hostname -I | awk '{print $1}'", intern = TRUE)
  options(shiny.host = hostIP)
}
Related