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

如何在Shiny应用中捕获并显示Plumber API的运行消息?

解决Plumber API运行消息在Shiny中展示的方案

要实现Shiny实时接收并展示Plumber API中slow_function的运行步骤,核心是让API流式输出消息,再让Shiny监听这个流来更新UI,完全不需要前端依赖目标R包。

1. 修改Plumber API端点(支持流式消息输出)

修改plumber.R,让/msg端点使用Server-Sent Events(SSE) 格式实时发送运行步骤,同时捕获slow_function的message输出:

# plumber.R
library(plumber)

slow_function <- function() {
  for (i in 1:5) {
    message(paste0("Step: ", i))
    Sys.sleep(1) # 模拟耗时操作
  }
  return("任务完成")
}

# 定义流式响应的msg端点
#* @get /msg
#* @serializer contentType list(type="text/event-stream")
function(res) {
  # 捕获slow_function的message输出
  withCallingHandlers({
    slow_function()
  }, message = function(m) {
    # 按SSE格式封装消息(必须以data: 开头,结尾加\n\n)
    sse_msg <- paste0("data: ", gsub("\n", "", m$message), "\n\n")
    res$write(sse_msg)
    res$flush() # 立即发送缓冲区内容,不等待函数执行完毕
    invokeRestart("muffleMessage") # 阻止消息默认输出到控制台
  })
  
  # 发送任务完成信号
  res$write("data: 任务完成\n\n")
  res$flush()
}

2. 修改Shiny应用(监听流式消息并更新UI)

使用httr2的流式请求功能,实时接收API发送的SSE消息,通过自定义消息更新Shiny界面:

# app.R
library(shiny)
library(httr2)

ui <- fluidPage(
  titlePanel("API运行步骤展示"),
  verbatimTextOutput("step_log")
)

server <- function(input, output, session) {
  # 初始化步骤日志
  step_log <- reactiveVal(c())
  
  # 发起流式请求并处理消息
  observe({
    req <- request("http://localhost:8000/msg") %>%
      req_headers(Accept = "text/event-stream") %>%
      req_stream(function(line) {
        # 解析SSE消息,提取data内容
        if (grepl("^data: ", line)) {
          new_step <- sub("^data: ", "", line)
          # 更新日志
          step_log(c(step_log(), new_step))
          # 发送自定义消息更新UI
          session$sendCustomMessage("update_log", step_log())
        }
      })
    
    # 执行请求
    req_perform(req)
  })
  
  # 监听自定义消息,实时渲染日志
  observeEvent(input$update_log, {
    output$step_log <- renderPrint({
      cat(paste(input$update_log, collapse = "\n"))
    })
  })
}

shinyApp(ui, server)

关键说明

  • SSE格式:Plumber端必须按data: 消息内容\n\n的格式发送,这是SSE的标准格式,Shiny端才能正确解析。
  • 流式响应:res$flush()确保每个步骤消息立即发送,而不是等slow_function执行完才返回所有内容。
  • 无依赖:Shiny只需要和Plumber API通信,完全不需要加载slow_function所在的R包。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:10:06