age*_*nis 6 session r global-variables shiny
我在应用程序中的shinydashboard某个地方使用 Shiny 应用程序工作,我想显示一条通知,告诉用户有多少其他用户同时连接到该应用程序。
我想出了第一段似乎有效的代码:
library(shiny)
ui=fluidPage(uiOutput("text"))
number.users <- 0 # global variable
server= function(input, output, session){
already.counted = FALSE
autoInvalidate = reactiveTimer(2000)
observe({
if (!already.counted) {
already.counted <- TRUE
number.users <<- number.users + 1
}
})
output$text = renderUI({
autoInvalidate()
h1(paste0("There are ", number.users, " user(s) connected to this app"))
})
onSessionEnded(function(){number.users <<- number.users - 1})
}
Run Code Online (Sandbox Code Playgroud)
然而,它不是很“干净”,我担心我observe每 2 秒的调用和无效会为我的(已经很重的)应用程序增加一些无用的计算时间。我想知道是否有某种函数可以在shiny每个新会话开始时触发事件,例如onsessionstart() 之类的 ,我可以直接使用它来增加全局变量number.users,以及一种通知其他会话新会话的方法已经开了吗?或者有没有更简单的方法?
谢谢
根服务器函数为每个新会话调用一次,并有效地用作“onSessionStart”回调。我认为你正在做的很好,除了observe不是真正必要的。
要以更具反应性的方式在会话之间共享全局状态,您可以在全局范围内(在反应性上下文之外)初始化一个reactiveValorreactiveValues对象,然后在每个会话中对其进行反应性依赖。对这些反应值的任何更新将立即传播到所有其他会话。
library(shiny)
users = reactiveValues(count = 0)
ui = fluidPage(uiOutput("text"))
server = function(input, output, session) {
onSessionStart = isolate({
users$count = users$count + 1
})
onSessionEnded(function() {
isolate({
users$count = users$count - 1
})
})
output$text = renderUI({
h1(paste0("There are ", users$count, " user(s) connected to this app"))
})
}
shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)
顺便说一句,会话间通信的一个更复杂的例子,虽然现在可能有点老了,是 Shiny 聊天室应用程序 - http://shiny.rstudio.com/gallery/chat-room.html