How do sessions work on a brilliant server?

I am having some problems understanding how sessions work on a brilliant server. I assume that the session ends when the user closes the browser, however, using print(session$isClosed()) in the server function, I get a FALSE response at the beginning (so good), and then when I close the browser, nothing happens. Can someone give me a hint about brilliant server sessions? I would like to store sessions for specific stories so that users can only upload their stories.

+5
source share
1 answer

Well, to start with a brilliant session object, this is a specific data structure ("R6") in brilliant form, consisting of public and private elements. The goal is to record one instance of the relationship between one user and one brilliant (more on this later).

 >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) 

A good way to examine a session object is to play with a brilliant example in a brilliant client-query-row-database . This allows you to see what is contained, for example, in session$clientdata or any other element of the object.

A few additional and misleading trivial points:

  • When does the session begin? When a user connects to a brilliant app
  • when does the session end? when the user disconnects from the brilliant application

As an example, to show how the problem is actually quite complicated, if I update the browser, I end the current session and create a new one.

Coming into session$isClosed() , this is the wrong function to connect to a specific action when the session ends. This is actually the role of a brilliant callback function

 onSessionEnded(fun, session = getDefaultReactiveDomain()) 

A minimal example might be the following:

 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)) 

If you try, updating (or tearing with a browser ()) will print β€œStop” and stop the application.

September 26, 2017 Edit:

In general, I think it's better to be careful if session continuity is important (and in any case, it is advisable to test the session code directly on Shiny Server or Shiny Server Pro ). Perhaps the most important use cases are Shiny Server Pro , where any shutdown may affect login status, etc.).

I also know that the shiny team has made changes to these areas in recent versions. For example, it seems that while onSessionEnded is still working, perhaps this is not the best function for this usecase.

For an example, see the following code (from the shiny reference manual) using onStop , which can work when a session ends and also when the application stops.

 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")) } ) 
+13
source

Source: https://habr.com/ru/post/1261663/


All Articles