R Shiny 可以同时为两个用户显示不同的视图,相互交互吗?
Can R Shiny display different views for two simultaneous users, interacting with one another?
通常情况下,Shiny 服务器会为单个用户生成单独的实例,以便多个人可以同时单独使用同一个应用程序。 shows how to make a simple multi-user chat room using Shiny, and this answer 解释多个用户如何通过直接 IP 连接到同一个会话。我让聊天示例正常工作,两个用户都可以在发送消息时立即看到消息,因此可以互相聊天。
我想知道是否有可能将 Shiny 用于一种(实验)场景,在这种场景中,两个用户相互交互,会在他们的屏幕上看到 不同的 GUI 元素各自的屏幕和不同的输出,取决于轮到谁 "play"。例如,如果 user1 是 "starting player",他会看到三个按钮并单击其中一个,会为 user2 弹出一个相关图像(而不是 user1),user2 单击一个按钮(他认为与图像匹配) ,然后为user1弹出相关图片,user1点击"correct"/"incorrect"按钮发送反馈;他们不应该看到谁点击了哪个按钮,也不应该看到另一个人看到的图像(如果实际上隐藏 GUI 元素很棘手,间歇性地使它们变灰 out/disabling 也很好,只要他们看不到另一个人在做什么) .
或更形象地说明:
round 1
user1 user2
director guesser
what they see, step by step:
1. [three buttons] [ (blank) ]
2. [clicks one] [ ]
3 [ ] [sees an image & 3 buttons]
4. [ ] [clicks a button]
5. [sees image,2 butns] [ ]
6. [clicks button] [ ]
7. [ ] [sees the message "correct" or "incorrect"]
round 2
user1 user2
guesser director
1. [ ] [three buttons]
...
...
下一轮他们交换角色,以此类推,进行多轮。
我见过使用 Javascript(jsPsych、nodegame)和 Python(psychopy、oTree)实现的类似实验场景,但我希望了解是否可以在有光泽,如果有,如何。
几年前,当我将“风险”(棋盘游戏)实现为一个闪亮的应用程序时,我遇到了同样的挑战。
简要概述我当时是如何处理它的:
如果您在服务器函数中使用 session
参数,您可以在该会话中/为该用户创建一个 local/secret reactiveValue()
。
接下来您可以在服务器功能之外设置 reactiveValues()
以获取跨会话访问的“全局信息”。
后一种方法可能更令人惊讶,因为我们通常“被迫”在服务器函数中定义 reactive
行为。但它有效,请参见下面的示例。
可重现的例子:
library(shiny)
ui <- fluidPage({
uiOutput("moreControls")
})
global <- reactiveValues(info = "public info: I can be seen by everyone", amountUser = 0, userIdToPlay = 1)
server <- function(input, output, session) {
local <- reactiveValues(secret = paste0("My secret number is ", sample(6, 1)))
observe({
isolate(global$amountUser <- global$amountUser + 1)
isolate(local$userId <- global$amountUser)
})
observeEvent(input$finish,{
global$userIdToPlay <- 3 - global$userIdToPlay # assumes two players (for MVE)
})
output$moreControls <- renderUI({
global$userIdToPlay
isolate({
if(local$userId == global$userIdToPlay){
return(
tagList(
h2("my time to play"),
selectInput("a", "b", letters),
actionButton("finish", "finish")
)
)
}else{
return(
h2("not my time to play")
)
}
})
})
}
shinyApp(ui, server)
通常情况下,Shiny 服务器会为单个用户生成单独的实例,以便多个人可以同时单独使用同一个应用程序。
我想知道是否有可能将 Shiny 用于一种(实验)场景,在这种场景中,两个用户相互交互,会在他们的屏幕上看到 不同的 GUI 元素各自的屏幕和不同的输出,取决于轮到谁 "play"。例如,如果 user1 是 "starting player",他会看到三个按钮并单击其中一个,会为 user2 弹出一个相关图像(而不是 user1),user2 单击一个按钮(他认为与图像匹配) ,然后为user1弹出相关图片,user1点击"correct"/"incorrect"按钮发送反馈;他们不应该看到谁点击了哪个按钮,也不应该看到另一个人看到的图像(如果实际上隐藏 GUI 元素很棘手,间歇性地使它们变灰 out/disabling 也很好,只要他们看不到另一个人在做什么) .
或更形象地说明:
round 1
user1 user2
director guesser
what they see, step by step:
1. [three buttons] [ (blank) ]
2. [clicks one] [ ]
3 [ ] [sees an image & 3 buttons]
4. [ ] [clicks a button]
5. [sees image,2 butns] [ ]
6. [clicks button] [ ]
7. [ ] [sees the message "correct" or "incorrect"]
round 2
user1 user2
guesser director
1. [ ] [three buttons]
...
...
下一轮他们交换角色,以此类推,进行多轮。
我见过使用 Javascript(jsPsych、nodegame)和 Python(psychopy、oTree)实现的类似实验场景,但我希望了解是否可以在有光泽,如果有,如何。
几年前,当我将“风险”(棋盘游戏)实现为一个闪亮的应用程序时,我遇到了同样的挑战。
简要概述我当时是如何处理它的:
如果您在服务器函数中使用 session
参数,您可以在该会话中/为该用户创建一个 local/secret reactiveValue()
。
接下来您可以在服务器功能之外设置 reactiveValues()
以获取跨会话访问的“全局信息”。
后一种方法可能更令人惊讶,因为我们通常“被迫”在服务器函数中定义 reactive
行为。但它有效,请参见下面的示例。
可重现的例子:
library(shiny)
ui <- fluidPage({
uiOutput("moreControls")
})
global <- reactiveValues(info = "public info: I can be seen by everyone", amountUser = 0, userIdToPlay = 1)
server <- function(input, output, session) {
local <- reactiveValues(secret = paste0("My secret number is ", sample(6, 1)))
observe({
isolate(global$amountUser <- global$amountUser + 1)
isolate(local$userId <- global$amountUser)
})
observeEvent(input$finish,{
global$userIdToPlay <- 3 - global$userIdToPlay # assumes two players (for MVE)
})
output$moreControls <- renderUI({
global$userIdToPlay
isolate({
if(local$userId == global$userIdToPlay){
return(
tagList(
h2("my time to play"),
selectInput("a", "b", letters),
actionButton("finish", "finish")
)
)
}else{
return(
h2("not my time to play")
)
}
})
})
}
shinyApp(ui, server)