Сроки завершения сеанса

Я создаю блестящее приложение, где я хочу остановить (локальный) сервер, когда клиент закрыт. Простым способом достижения этого является включение этого в функцию shinyServer:

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

Недостатком этого подхода является то, что пользователь решает поразить обновление, затем приложение умирает.

Я пробовал различные обходные пути, используя, например, reactiveTimer/invalidateLater для проверки соединений через определенные промежутки времени. Однако они берут ссылку на сеанс (они специфичны для сеанса), и поэтому после onSessionEnded ничего не будет выполнено.

Есть ли способ иметь "глобальный" таймер сервера, который выполняется регулярно и может проверять наличие активных соединений? Или другой способ добиться автоматического отключения приложения, но который позволяет обновить страницу?

Ответ 1

Вы можете добавить actionButton и некоторый код на сервере, чтобы остановить приложение при нажатии кнопки. Например:

runApp(list(
  ui = bootstrapPage(
    actionButton('close', "Close app")
  ),
  server = function(input, output) {
    observe({
      if (input$close > 0) stopApp()
    })
  }
))

Однако это не приведет к автоматическому закрытию окна браузера (если вы не просмотрите его с помощью встроенного окна браузера RStudio). Для этого вам нужно добавить Javascript в actionButton.

runApp(list(
  ui = bootstrapPage(
    tags$button(
      id = 'close',
      type = "button",
      class = "btn action-button",
      onclick = "setTimeout(function(){window.close();},500);",
      "Close window"
    )
  ),
  server = function(input, output) {
    observe({
      if (input$close > 0) stopApp()
    })
  }
))

Конечно, это не остановит приложение, когда пользователь закроет окно каким-либо другим способом. Я считаю, что также возможно обнаружить события закрытия окна в браузере, а затем вы можете установить значение ввода (которое идет на сервер) в то время, но я не знаю, получит ли он сервер перед закрытием окна, и Javascript перестает работать.