【问题标题】:How to stop running shiny app by closing the browser window?如何通过关闭浏览器窗口来停止运行闪亮的应用程序?
【发布时间】:2016-05-20 06:41:52
【问题描述】:

我在 shinyapps.io 中部署了一个应用程序,并且运行良好。

我只运行了 5 分钟的应用程序,但是当我检查指标时,它显示运行时间约为 0.7 小时。我发现有一个默认的 15 分钟空闲时间,我已将其更改为 5 分钟(最小值)。我还注意到,即使在关闭闪亮应用程序的浏览器窗口后,它仍然显示该应用程序在我的仪表板中运行。

我假设当浏览器窗口关闭时应用程序不会停止运行,它只会在满足空闲时间条件时停止。

有没有办法在浏览器窗口关闭时停止闪亮的应用程序?下面这段代码在这种情况下可以工作吗?

session$onSessionEnded(function() {
    stopApp()
  })

【问题讨论】:

  • 你应该在shinyapps用户谷歌组中问这个
  • 一个JavaScript eventstopApp()?
  • 该问的人肯定是@daattali,因为他的示例应用程序在一段时间后变灰,它认为它需要 15 分钟
  • 我之前给出的答案在您的编辑中使用了确切的代码,我想知道您的解决方案是否来自我? :) 无论如何,该代码将在会话结束时终止应用程序。当您在浏览器中本地运行应用程序时,关闭窗口绝对算作会话结束。但是,我对shinyappsio 非常不熟悉,所以我不确定它是否在shinyapps 中那样工作。有可能是这样,但可以肯定的是,我会在shinyapps 讨论板中询问,或者只是尝试并尝试看看会发生什么
  • 我从 google 群组获得了代码,我不知道是不是你的。不幸的是,该代码在 shinyappsio 中不起作用。我也试过q("no")stopApp 没有结果。我必须从仪表板手动关闭应用程序。为什么我担心的是,仅通过访问应用程序 url,我们就启动了应用程序,它仅在 5 分钟空闲时间后停止。由于我使用的是 25 小时的免费套餐,因此应用程序需要花费大量宝贵的时间:(

标签: r shiny shinydashboard


【解决方案1】:

我添加了这个inactivity JS 代码来帮助我处理一些空闲的闪亮应用程序。该代码几乎是不言自明的,我在其中跟踪鼠标移动和点击。请注意,此应用将在 5 秒后关闭。

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),  
  actionButton("recalc","recalc"),
  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))

【讨论】:

  • 嘿@Pork Chop,在你的server.R中你有input$recalc。这个 input$recalc 来自哪里?我没有看到任何 id = "recalc" 的用户输入。谢谢。
  • @JordanWrong 我添加了按钮,这是任意的,因为这个问题不需要它
【解决方案2】:

我不知道shinyapps.io,但在R 中(如您的标签所示),您确实可以通过onSessionEnded 停止shinyApp。以下是一个最小的工作示例。

rm(list=ls())

library(shiny)

doshiny <- function() {
  app=shinyApp(
    ui = fluidPage(
      textInput("textfield", "Insert some text", value = "SomeText")
    ),
    server = function(input, output, session) {
      session$onSessionEnded(function() {
        stopApp()
      })
    }
  )
  runApp(app)
}

openshiny <- function() {
  doshiny()
  print("Finished.")
}

openshiny()

【讨论】:

  • 这是个坏主意!如果多个用户连接到应用程序,那么一个用户(或浏览器选项卡)退出将导致所有人被踢出!
【解决方案3】:

我发现这个excellent code 可以完成这项工作。基本上,你会这样做:

library(shiny)
library(shinyjs)

jscode <- "shinyjs.closeWindow = function() { window.close(); }"

ui <- fluidPage(
  useShinyjs(),
  extendShinyjs(text = jscode, functions = c("closeWindow")),
  actionButton("close", "Close window")
)

server <- function(input, output, session) {
  observeEvent(input$close, {
    js$closeWindow()
    stopApp()
  })
}

shinyApp(ui, server)

请注意,虽然可能禁止通过 JavaScript 关闭浏览器窗口。但这是another discussion

【讨论】:

  • 这个只对第一个客户端有效,如果当前有很多,其余的不会关闭
猜你喜欢
  • 2020-09-30
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多