2016-12-21 4 views
5

반짝이는 서버에서 세션이 어떻게 작동하는지 이해하는 데 몇 가지 문제가 있습니다. 사용자가 브라우저를 닫을 때 세션이 완료된다고 가정하지만 서버 기능에 을 사용하면 처음에는 응답이 FALSE으로 시작되고 브라우저가 닫히면 아무 일도 일어나지 않습니다. 누구든지 반짝이는 서버 세션에 대한 단서를 줄 수 있습니까? 사용자가 자신의 플롯을 다운로드 할 수 있도록 세션 별 플롯을 저장하려고합니다.세션이 반짝이는 서버에서 어떻게 작동합니까?

답변

13

반짝이는 세션 객체는 공개 및 비공개 요소로 구성된 반짝이는 특정 ('R6') 데이터 구조입니다. 특정 사용자와 반짝이는 관계를 하나의 사례로 기록하는 것이 목적입니다.

>str(session) 
Classes 'ShinySession', 'R6' <ShinySession> 
    Public: 
    @uploadEnd: function (jobId, inputId) 
    @uploadieFinish: function() 
    @uploadInit: function (fileInfos) 
    allowReconnect: function (value) 
    clientData: reactivevalues 
    clone: function (deep = FALSE) 
    close: function() 
    closed: FALSE 
    decrementBusyCount: function() 
    defineOutput: function (name, func, label) 
    dispatch: function (msg) 
    doBookmark: function() 
    downloads: Map, R6 
    exportTestValues: function (..., quoted_ = FALSE, env_ = parent.frame()) 
    files: Map, R6 
    fileUrl: function (name, file, contentType = "application/octet-stream") 
    flushOutput: function() 
    freezeValue: function (x, name) 
    getBookmarkExclude: function() 
    getTestEndpointUrl: function (inputs = TRUE, outputs = TRUE, exports = TRUE, format = "rds") 
    groups: NULL 
    handleRequest: function (req) 
    incrementBusyCount: function() 
    initialize: function (websocket) 
    input: reactivevalues 
    isClosed: function() 
    isEnded: function() 
    makeScope: function (namespace) 
    manageHiddenOutputs: function() 
    manageInputs: function (data) 
    ns: function (id) 
    onBookmark: function (fun) 
    onBookmarked: function (fun) 
    onEnded: function (endedCallback) 
    onFlush: function (flushCallback, once = TRUE) 
    onFlushed: function (flushedCallback, once = TRUE) 
    onInputReceived: function (callback) 
    onRestore: function (fun) 
    onRestored: function (fun) 
    onSessionEnded: function (sessionEndedCallback) 
    output: shinyoutput 
    outputOptions: function (name, ...) 
    progressStack: environment 
    reactlog: function (logEntry) 
    registerDataObj: function (name, data, filterFunc) 
    registerDownload: function (name, filename, contentType, func) 
    reload: function() 
    request: environment 
    resetBrush: function (brushId) 
    restoreContext: RestoreContext, R6 
    rootScope: function() 
    saveFileUrl: function (name, data, contentType, extra = list()) 
    sendBinaryMessage: function (type, message) 
    sendCustomMessage: function (type, message) 
    sendInputMessage: function (inputId, message) 
    sendInsertUI: function (selector, multiple, where, content) 
    sendModal: function (type, message) 
    sendNotification: function (type, message) 
    sendProgress: function (type, message) 
    sendRemoveUI: function (selector, multiple) 
    session: active binding 
    setBookmarkExclude: function (names) 
    setShowcase: function (value) 
    showProgress: function (id) 
    singletons: 
    token: d44d583f13b3cd4ccce43f59fe410f61 
    unhandledError: function (e) 
    updateQueryString: function (queryString) 
    user: NULL 
    wsClosed: function() 
    Private: 
    .clientData: ReactiveValues, R6 
    .input: ReactiveValues, R6 
    .outputOptions: list 
    .outputs: list 
    bookmarkCallbacks: environment 
    bookmarkedCallbacks: environment 
    bookmarkExclude: 
    busyCount: 2 
    closedCallbacks: environment 
    createBookmarkObservers: function() 
    enableTestEndpoint: function() 
    fileUploadContext: environment 
    flushCallbacks: environment 
    flushedCallbacks: environment 
    getOutputOption: function (outputName, propertyName, defaultValue) 
    inputMessageQueue: list 
    inputReceivedCallbacks: environment 
    invalidatedOutputErrors: Map, R6 
    invalidatedOutputValues: Map, R6 
    outputValues: list 
    progressKeys: character 
    registerSessionEndCallbacks: function() 
    restoreCallbacks: environment 
    restoredCallbacks: environment 
    sendErrorResponse: function (requestMsg, error) 
    sendMessage: function (...) 
    sendResponse: function (requestMsg, value) 
    shouldSuspend: function (name) 
    showcase: FALSE 
    storeOutputValues: function (values = NULL) 
    testEndpointUrl: session/d44d583f13b3cd4ccce43f59fe410f61/dataobj/shinyte ... 
    testValueExprs: list 
    websocket: WebSocket 
    write: function (json) 

세션 객체를 탐구하는 좋은 방법은 shiny example in shiny gallery client-data-and-query-string으로 재생하는 것입니다. 그것은 예를 들어 session$clientdata 또는 객체의 다른 요소에 포함 된 내용을 see으로 허용합니다.

추가 & 오해 사소한 점 몇 :

  • 세션 시작을 수행 할 때? 사용자가 반짝이는 앱과 연결할 때
  • 세션이 끝나는 시점은 언제입니까? 사용자가 반짝이는 앱을 사용하여 연결을 끊을 때

예를 들어 문제가 실제로 얼마나 복잡한 지 보여주기 위해 브라우저를 새로 고침하면 현재 세션이 종료되고 새 세션이 만들어집니다.

session$isClosed()에 오면 이는 세션이 끝날 때 특정 작업에 연결하는 올바른 기능이 아닙니다. 이 실제로 최소한의 예는 다음 될 수있는 반짝 콜백 기능

onSessionEnded(fun, session = getDefaultReactiveDomain()) 

의 역할이다 : 당신이하려고하면

library(shiny) 

ui =(
    fluidPage(
    titlePanel("This is an example") 
) 
) 

server = function(input, output, session){ 
    session$onSessionEnded({ 
    print("Stop!") 
    stopApp 
    }) 
} 

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

새로 고침 (또는 브라우저 분할하기를()) 인쇄됩니다 "중지"하고 앱을 중지합니다.

2017년 9월 26일 편집 : 일반적으로

, 내가 세션의 연속성이 중요하다 (그리고 어떤 경우는 Shiny Server에 직접 session 코드를 테스트하는 것이 적절한 경우는주의하는 것이 좋습니다 생각 또는 Shiny Server Pro). 아마도 가장 중요한 사용 사례는 Shiny Server Pro이며, 단절 may은 로그인 상태 등에 영향을줍니다.)

최근 버전에서는 shiny 팀이이 부분을 변경 한 사실을 알고 있습니다. 예를 들어, onSessionEnded이 아직 작동하는 동안이 유스 케이스에 대한 최상의 기능이 아닌 것으로 보입니다.

을 사용하여 다음 코드를 예제로 사용하십시오 (shiny 참조 가이드에서). 세션이 끝날 때뿐만 아니라 앱이 멈출 때도 작동합니다.

library(shiny) 

cat("Doing application setup\n") 
onStop(function() { 
    cat("Doing application cleanup\n") 
}) 

shinyApp(
    ui = basicPage("onStop demo"), 

    server = function(input, output, session) { 
    onStop(function() cat("Session stopped\n")) 
    } 
) 
+0

다음 진술에 대해 확실합니까? "브라우저()로 반짝이는 앱을 디버그하면 휴식 시간에 앱이 중단되면 현재 세션이 종료됩니다." ? 나는 그것이 사실이라고 생각하지 않는다. 또한 세션 종료시 실행되지 않고 세션이 시작될 때 실행되기 때문에 샘플 코드의'print ("Stop!")은 오해의 소지가 있습니다. 세션이 끝나면 stopApp 콜백 만 호출됩니다. 나는이 정보 중 일부가 잘못되었다고 생각한다. –

+0

'반짝 반짝'은'세션 '이 중단 될 때의 행동을 되돌려 놓았다고 생각합니다. (나는 게시물에 경고를 추가 할 것입니다.) 나는'session # token'이'browser()'를 사용하여 디버그하는 동안 변경되는지 여부를 재확인했으며 실제로 토큰은 동일하게 유지됩니다. 나는 @Dean Attali 코멘트도 약간 잘못 생각한다 : 반짝이는 심판에 따르면. "onSessionEnded는 클라이언트 연결이 끊어진 후에 호출 할 함수를 등록합니다."즉, 연결 해제 후 실제로 함수가 실행된다는 의미입니다. 예 : 과거에는'session $ onSessionEnded'를 사용하여 응용 프로그램의 일부 상태로 파일을 저장하거나 데이터베이스에서 연결을 끊습니다. – Enzo

+0

'onSessionEnded()'는 함수 콜백을 등록하지만, 내가 말한 것은 여전히 ​​정확합니다. 시험해보십시오. print 문은 시작시 즉시 실행됩니다. 그 이유는'onSessionEnded()'가 ** 함수 **를 기대하기 때문입니다. 그러나 당신은 print 문을 포함하고 ** 함수를 포함하는 ** 표현식 **을 넘겼습니다. 두 번째 줄인'stopApp'는 세션이 끝날 때 호출되는 함수입니다. 그러나 표현식 내의 코드는 즉시 실행됩니다. 원하는 동작을 얻으려면'onSessionEnded (function() {print (...); stopApp())'가 필요하다고 생각합니다. –