Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shiny server session time out doesn't work

I have a shiny app deployed on a Linux server. I want the app to timeout if there is no activity for a minute. Based on what I read, I added the line app_idle_timeout to the shiny-server.conf file but I notice that it doesn't work. Can someone please advice how I can ensure that the session times out after a minute? Note: I do NOT have shiny server PRO.

Below is what my shiny-server.conf looks like.

Instruct Shiny Server to run applications as the user "shiny"
run_as shiny;

# Define a server that listens on port 3838
server {
  listen 3838;

  # Define a location at the base URL
  location / {

    # Host the directory of Shiny Apps stored in this directory
    site_dir /srv/shiny-server;

    # Log all Shiny output to files in this directory
    log_dir /var/log/shiny-server;
    app_idle_timeout 60;

    # When a user visits the base URL rather than a particular application,
    # an index of the applications available in this directory will be shown.
    directory_index on;

  }
}
~                 
like image 459
rookieJoe Avatar asked Nov 21 '15 03:11

rookieJoe


People also ask

What is session in shiny server?

Shiny server functions can optionally include session as a parameter (e.g. function(input, output, session) ). The session object is an environment that can be used to access information and functionality relating to the session.

Why is shiny so slow?

There are many reasons why a shiny app runs slower than expected. The most common reason is the Shiny app code has not been optimized. You can use the profvis package to help you understand how R spends its time. You also might want to make sure your server is large enough to host your apps.

How does R shiny server work?

Shiny Server is an open source back end program that makes a big difference. It builds a web server specifically designed to host Shiny apps. With Shiny Server you can host your apps in a controlled environment, like inside your organization, so your Shiny app (and whatever data it needs) will never leave your control.


2 Answers

You can configure your idle time within the shiny app like so using some JS, here the app will timeout after 5 seconds.

library(shiny)
library(leaflet)

inactivity <- "function idleTimer() {
  var t = setTimeout(logout, 5000);
  window.onmousemove = resetTimer; // catches mouse movements
  window.onmousedown = resetTimer; // catches mouse movements
  window.onclick = resetTimer;     // catches mouse clicks
  window.onscroll = resetTimer;    // catches scrolling
  window.onkeypress = resetTimer;  //catches keyboard actions

  function logout() {
    window.close();  //close the window
  }

  function resetTimer() {
    clearTimeout(t);
    t = setTimeout(logout, 5000);  // time is in milliseconds (1000 is 1 second)
  }
}
idleTimer();"


ui <- fluidPage(
  tags$script(inactivity),    
  leafletOutput("mymap")

)

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

  points <- eventReactive(input$recalc, {
    cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
  }, ignoreNULL = FALSE)

  output$mymap <- renderLeaflet({
    leaflet() %>%
      addProviderTiles(providers$Stamen.TonerLite,options = providerTileOptions(noWrap = TRUE)) %>% 
      addMarkers(data = points())
  })

})
runApp(list(ui = ui, server = server))
like image 171
Pork Chop Avatar answered Sep 19 '22 07:09

Pork Chop


@PorkChop, thanks for your very useful answer!

Just for the sake of completeness, here is a slightly modified version of @PorkChop's code which doesen't close the browser tab, but instead only closes the session and leaves a message for the user:

library(shiny)
library(leaflet)

timeoutSeconds <- 5

inactivity <- sprintf("function idleTimer() {
var t = setTimeout(logout, %s);
window.onmousemove = resetTimer; // catches mouse movements
window.onmousedown = resetTimer; // catches mouse movements
window.onclick = resetTimer;     // catches mouse clicks
window.onscroll = resetTimer;    // catches scrolling
window.onkeypress = resetTimer;  //catches keyboard actions

function logout() {
Shiny.setInputValue('timeOut', '%ss')
}

function resetTimer() {
clearTimeout(t);
t = setTimeout(logout, %s);  // time is in milliseconds (1000 is 1 second)
}
}
idleTimer();", timeoutSeconds*1000, timeoutSeconds, timeoutSeconds*1000)


ui <- fluidPage(
  tags$script(inactivity),    
  leafletOutput("mymap")
)

server <- shinyServer(function(input,output,session){
  
  observeEvent(input$timeOut, { 
    print(paste0("Session (", session$token, ") timed out at: ", Sys.time()))
    showModal(modalDialog(
      title = "Timeout",
      paste("Session timeout due to", input$timeOut, "inactivity -", Sys.time()),
      footer = NULL
    ))
    session$close()
  })
  
  points <- eventReactive(input$recalc, {
    cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
  }, ignoreNULL = FALSE)
  
  output$mymap <- renderLeaflet({
    leaflet() %>%
      addProviderTiles(providers$Stamen.TonerLite, options = providerTileOptions(noWrap = TRUE)) %>% 
      addMarkers(data = points())
  })
  
})

runApp(list(ui = ui, server = server))

result

This was very helpful to get here.

like image 44
ismirsehregal Avatar answered Sep 20 '22 07:09

ismirsehregal