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

Ubuntu R Connect Server部署Shiny应用实现桌面推送通知可行吗?

在Ubuntu R Connect Server上实现Shiny应用桌面推送通知

可行性结论

技术上完全可行。你本地Windows RStudio环境能用但部署后失效,核心原因是:

  • 本地localhost属于浏览器允许的HTTP例外场景,而部署到R Connect Server后,浏览器的桌面通知API要求网站必须使用HTTPS协议
  • 你使用的use_push()函数大概率依赖浏览器原生Notification API,但部署后可能缺少权限请求流程,或R Connect未配置HTTPS导致通知被拦截

实现方案

方案1:基于浏览器原生Notification API的适配实现(最简便)

先确保你的R Connect Server已配置HTTPS(这是浏览器允许桌面通知的硬性要求),然后用原生JS结合Shiny消息机制实现,替代依赖本地环境的use_push():

ui <- fluidPage(
  tags$h2("桌面推送通知"),
  # 自定义JS处理通知权限和推送逻辑
  tags$script(HTML('
    // 页面加载时请求通知权限
    async function requestNotifyPermission() {
      const permission = await Notification.requestPermission();
      if (permission !== "granted") {
        alert("请允许浏览器通知权限,否则无法接收推送");
      }
    }
    window.addEventListener("load", requestNotifyPermission);

    // 发送桌面通知的函数
    function showDesktopNotify(title) {
      if (Notification.permission === "granted") {
        new Notification(title, {
          body: "来自Shiny应用的通知",
          // 可选:指定通知图标,需将图标放在应用的www目录下
          // icon: "notification-icon.png"
        });
      }
    }

    // 监听Shiny服务器发来的消息
    Shiny.addCustomMessageHandler("triggerNotify", function(msg) {
      showDesktopNotify(msg.title);
    });
  ')),
  actionButton("show", "显示通知"),
  textInput("title", "通知内容", "Hello world :)")
)

server <- function(input, output, session) {
  observeEvent(input$show, {
    # 向前端发送触发通知的消息
    session$sendCustomMessage(
      type = "triggerNotify",
      message = list(title = input$title)
    )
  })
}

shinyApp(ui, server)

部署后用户首次打开应用会收到浏览器的权限请求,允许后即可在任意窗口状态下接收桌面通知。

方案2:基于Web Push协议的实现(支持离线通知)

如果需要用户关闭浏览器后仍能接收通知,可采用Web Push协议,需额外配置:

  1. 生成VAPID密钥对:用于服务端与浏览器的身份验证(可通过Node.js的web-push包生成)
  2. 注册Service Worker:在Shiny UI中添加Service Worker注册逻辑
  3. 编写Service Worker脚本:处理推送事件并展示通知
  4. R端发送推送:使用webpush包结合用户订阅信息发送通知

核心代码示例:

  • UI中注册Service Worker:
tags$script(HTML('
  if ("serviceWorker" in navigator) {
    window.addEventListener("load", async () => {
      const registration = await navigator.serviceWorker.register("/sw.js");
      // 订阅推送并将订阅信息发送给Shiny服务器
      const subscription = await registration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: "你的VAPID公钥"
      });
      Shiny.setInputValue("push_subscription", JSON.stringify(subscription));
    });
  }
'))
  • 编写sw.js(放在应用www目录下):
self.addEventListener("push", (event) => {
  const data = event.data.json();
  const notifyOptions = {
    body: data.body,
    icon: "notification-icon.png"
  };
  event.waitUntil(
    self.registration.showNotification(data.title, notifyOptions)
  );
});
  • Server端发送推送:
library(webpush)

observeEvent(input$show, {
  # 解析用户订阅信息
  subscription <- jsonlite::fromJSON(input$push_subscription)
  # 发送推送
  webpush(
    subscription = subscription,
    payload = jsonlite::toJSON(list(title = input$title, body = "Shiny应用推送")),
    vapid_pubkey = "你的VAPID公钥",
    vapid_prvkey = "你的VAPID私钥",
    vapid_email = "你的邮箱"
  )
})

该方案配置复杂,但支持离线推送,适合长期通知场景。

方案3:第三方通知服务替代(简单但间接)

如果不想处理Web Push的复杂配置,可通过以下间接方式实现:

  • 将通知内容发送到用户邮箱,让用户设置邮箱客户端的桌面提醒
  • 集成企业级通知服务(如钉钉、企业微信机器人),通过API发送消息到用户客户端

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 11:22:48