3

この質問は確かにこの質問に似ていますが、提供された回答は私の例には十分ではありません。

データベースに接続する光沢のあるアプリを作成しています。ユーザーはいくつかの入力を提供でき、いくつかの「既定の」クエリが実行されます。ここで、アプリの終了時にデータベースへの接続が閉じていることを確認したいと思います。ボタンとstopApp関数を使用することもできますが、これはユーザーが適切で、常にそのボタンをクリックすることを前提としています。ユーザーは、データベース接続を開いたままウィンドウを閉じる可能性があるため、ユーザーがアプリ ウィンドウを閉じたときに接続を明示的に閉じる方法を見つけたいと考えています。

1 つの解決策は、新しい接続をインスタンス化し、各クエリの最後に閉じることだと思いますが、それは非効率的です。

問題を示すための実用的なコードを次に示します。Rstudio からこのアプリを実行してからウィンドウを閉じても、 に従って既存の接続が残っていますdbListConnections(PostgreSQL())。ファイルの末尾に追加dbDisconnect(con)しても役に立ちません。

library(shiny)
library(RPostgreSQL)

server <- shinyServer(function(input, output){
  # Read in the dataset
  connectDB <- eventReactive(input$connectDB, {

    if(input$drv != "postgresql"){
      stop("Only 'postgresql' implemented currently")
    }else{
      drv <- dbDriver("PostgreSQL")
      port = 5432
    }

    con <- dbConnect(drv, user = input$user, password = input$passwd, 
                     port = port, host = input$server, dbname=input$db_name)
    con
  })

  output$test <- renderText({
    con <- connectDB()
    "connection success"
  })
})


ui <- shinyUI(
  fluidPage(
    titlePanel("Test Connection"),

    sidebarLayout(
      sidebarPanel(
        textInput("drv", "Database Driver", value="postgresql"),
        textInput("user", "User ID"),
        textInput("server", "Server", value="server"),
        textInput("db_name", "Database Name", value="dbName"),
        passwordInput("passwd", "Password"),
        actionButton("connectDB", "Connect to DB")
      ),

      mainPanel(
        textOutput("test")
      )
    )
  )
)

shinyApp(ui=ui, server=server)
4

1 に答える 1

7

変数の について知ってonSessionEndedいますか?session

これは非常に基本的な例で、各ユーザーにランダムなセッション ID を設定し、ユーザーがウィンドウを閉じると、どのセッション ID が閉じられたかを示す関数が実行されます。これは単なる概念実証です。データベースのニーズに合わせて簡単に調整できます

runApp(shinyApp(
  ui = fluidPage(
    textOutput("sessionId")
  ),
  server = function(input, output, session) {
    sessionId <- as.integer(runif(1, 1, 100000))
    output$sessionId <- renderText(paste0("Session id: ", sessionId))
    session$onSessionEnded(function() {
      cat(paste0("Ended: ", sessionId))
    })
  }
))

編集:

Op は変数をリアクティブにする必要があると言いました。

runApp(shinyApp(
  ui = fluidPage(
    textOutput("sessionId")
  ),
  server = function(input, output, session) {
    values <- reactiveValues(sessionId = NULL)
    values$sessionId <- as.integer(runif(1, 1, 100000))
    output$sessionId <- renderText(paste0("Session id: ", values$sessionId))
    session$onSessionEnded(function() {
      observe(cat(paste0("Ended: ", values$sessionId)))
    })
  }
))

免責事項: onSessionEnded コールバック内に監視を配置することが最善の方法であるかどうかはわかりません。これは機能しますが、「正しさ」を保証することはできません。

于 2015-07-02T18:47:25.653 に答える