2015-07-02 51 views
2

這個問題無可否認類似於this question,但提供的答案不足以滿足我的示例。當關閉R時,從PostgreSQL斷開連接閃亮的應用

我正在創建一個連接到數據庫的Shiny應用程序。用戶可以提供一些輸入,並且一些「預置」查詢將會運行。現在,我想確保從應用程序退出時關閉與數據庫的連接。我可以使用一個按鈕和stopApp函數,但是這假設用戶會很好,並且總是單擊所述按鈕。用戶有時可能會關閉窗口而使數據庫連接處於打開狀態,所以我想找到一種在用戶關閉應用程序窗口時明確關閉連接的方法。

我想一種解決方案是實例化一個新的連接,並在每個查詢結束時關閉,但似乎效率低下。

下面是一些工作代碼來演示問題。如果我從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) 
+1

也許使用'session $ onSessionEnded'? – hrbrmstr

回答

4

你瞭解session變量的onSessionEnded

這是一個非常基本的例子,它爲每個用戶設置一個隨機的會話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)) 
    }) 
    } 
)) 

編輯:

運說,他所需要的變量是被動的,所以這裏的,我認爲修改會讓他他想要的東西

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回調內部的觀察是最好的辦法。這有效,但我不能保證它是「正確的」。

+0

謝謝,我不知道'onSessionEnded'變量。應該考慮看會話對象文檔。爲了徹底解決我的問題,我需要創建一個全局變量來引用現有的連接,但這使我能夠做到這一點。 – cdeterman

+0

如果你只有一個用戶連接的時間沒有問題。如果你允許多個用戶連接,那麼當第一個用戶離開時,我認爲這將導致所有連接死掉,因爲所有會話都共享相同的全局連接 –

+0

有效的點,你有沒有另一個想法如何獲得反應連接對象? – cdeterman

相關問題