You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用WebSocket空闲超时问题求解决方案

解决Shiny应用负载均衡下WebSocket超时的心跳方案

这个问题在负载均衡环境下太常见了——负载均衡器盯着空闲连接,60秒没数据就直接断开,完全不管你的应用本身跑得多正常。好在我们有几种靠谱的方法给WebSocket加心跳,让负载均衡器以为连接一直“活着”。

方法一:前端主动发送心跳信号

最简单的方式是让浏览器每隔一段时间主动给Shiny服务器发个小消息,触发WebSocket通信。这种方法不需要改太多后端代码,前端加段JS就行:

ui <- fluidPage(
  # 插入心跳脚本,每隔30秒发送一个时间戳到服务器
  tags$script(HTML("
    setInterval(() => {
      // 用Shiny的内置方法发送输入值,服务器不需要处理这个值
      Shiny.setInputValue('keep_alive_heartbeat', Date.now());
    }, 30000); // 30秒间隔,比负载均衡的60秒超时短就行
  ")),
  
  # 你的其他UI组件...
)

server <- function(input, output, session) {
  # 这里不需要额外处理heartbeat输入,只要它存在,WebSocket就会有数据传输
  # 你的业务逻辑代码...
}

只要这个定时任务在跑,浏览器就会每隔30秒发个小数据,负载均衡器就不会认为连接空闲了。

方法二:后端定时推送心跳消息

如果更倾向于从服务器端控制心跳,也可以用Shiny的响应式定时器,每隔一段时间给前端发个自定义消息:

server <- function(input, output, session) {
  # 创建一个30秒触发一次的定时器
  heartbeat_timer <- reactiveTimer(30000)
  
  observe({
    heartbeat_timer()
    # 发送一个空的自定义消息,触发WebSocket通信
    session$sendCustomMessage(type = "heartbeat", message = list())
  })
  
  # 你的业务逻辑代码...
}

前端不需要额外处理这个消息,只要服务器推送了数据,WebSocket连接就会保持活跃。同样,间隔要设得比负载均衡的60秒超时短,比如30秒或者45秒都可以。

注意事项

  • 心跳间隔一定要小于负载均衡器的超时时间(比如设为30秒,比60秒超时短一半),避免刚好在超时前没赶上。
  • 两种方法选一种就行,不用同时用,不然反而增加不必要的通信量。
  • 如果用前端方法,不用担心服务器端的资源消耗——这个输入只是个时间戳,Shiny会自动处理,不需要你写额外的响应逻辑。

内容的提问来源于stack exchange,提问作者user1915201

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:39:37