如何在没有后端服务器的情况下在 24 小时后触发桌面通知?
Posted
技术标签:
【中文标题】如何在没有后端服务器的情况下在 24 小时后触发桌面通知?【英文标题】:How to trigger desktop notification 24 hours later without backend server? 【发布时间】:2018-12-16 14:56:28 【问题描述】:假设:
-
用户已允许我的网站上的通知。
Service Worker 已安装并准备就绪。
用户将客户端提醒设置为从现在起 24 小时后提醒。
没有后端服务或服务器将通知推送给用户。
如果没有后端服务器推送通知,我如何触发桌面通知?这可能吗?
如果提供了超时/间隔并且web-alarm/task-scheduler specification 尚未准备好使用,则服务工作者将被浏览器关闭。是否没有客户端唯一的方法来在未来某个指定时间触发通知?
是否有严格意义上不是“推送通知”的桌面通知?推送通知本质上是从服务器推送的。可以从客户端触发通知吗?
【问题讨论】:
浏览器扩展是一种选择吗?即使用户不再在页面上,他们也可能会在 24 小时后发送通知。 是的,@JochenJung 浏览器扩展是一个选项。 【参考方案1】:我认为目前这是不可能的。
推送通知在RFC8030 中指定,来自其摘要:
本文档描述了一个用于交付真实的简单协议- 用户代理的时间事件。该方案使用 HTTP/2 服务器推送。
这意味着需要支持 HTTP/2 推送的服务器。
我确实喜欢对 javascript 大喊大叫,而且我似乎无法找到在浏览器中运行的 HTTP2 服务器的 Javascript 实现(有节点),这对我来说是一种耻辱,并且会是真棒。
所以,为了名利,http2-server.js 不见了。
【讨论】:
了解“推送”通知。我认为推送通知本质上将需要后端服务器来推送它。我希望有一个可以在特定时间触发的桌面通知,作为提醒或警报。 我认为目前服务工作者不可能,因为由于浏览器关闭非活动工作者,超时或间隔将被忽略。我希望得到确认。 可能确实如此。如果你有什么发现,请发布。 当然可以。是否存在仅限客户端的解决方案是非常值得怀疑的。【参考方案2】:您或许可以考虑使用localStorage。但是,这仅对使用相同设备和浏览器的用户有益。
以下是在页面加载时启动的功能。如果您希望它在整个会话期间定期发生,您可以将其包装成 setInterval
并定期检查。这是假设它需要精确到毫秒后 24 小时。
// on page load
window.onload = () =>
const dayMs = 24*60*60*1000; // 1 day in milliseconds
const notificationTimer = localStorage.getItem('notificationTimer');
if(notificationTimer)
const sendNotification = (Date.now() - (new Date(notificationTimer)).getTime()) > dayMs;
if(sendNotification)
const notification = new Notification('Displaying next day reminder from yesterday');
;
当用户选择第二天提醒时,您可以设置notificationTimer
:
localStorage.setItem(notificationTimer, Date.now());
您必须对第二天的提醒在浏览器或设备上不起作用提出一些警告,这可能是可取的,也可能是不可取的。
【讨论】:
这是一个很好的选择@Joe,除了我认为 OP 正在寻找更多“推送通知”类型的解决方案 - 即即使用户不浏览也能工作的解决方案网站。 Mortz 是正确的,即使用户没有浏览网站也希望收到通知。 呃,这个答案被社区自动授予赏金,因为我延迟选择。我仍在寻找 24 小时后触发通知的方法。打开的网站不应该是一个要求,但如果浏览器是打开的就可以了。也许使用像@JochenJung 提到的浏览器扩展。【参考方案3】:在撰写本文时(2019 年 1 月 3 日):
如果您的应用不在后台运行,则无法触发“桌面通知”。 Service Worker 不应该使用计时器,将被关闭。 操作系统或其他实用软件也可能会建议甚至关闭您的后台应用程序。 没有客户端唯一的方法可以在未来的准确时间触发您的通知。组织目前不允许这种情况发生的原因太多了。没有“桌面通知”不是严格意义上的“推送通知”并且可以跨平台运行。
您唯一的选择似乎是使用不同的推送通知服务和外部调度服务,该服务将根据自定义调度触发外部通知。
每个访问者都需要订阅推送通知 外部记录客户偏好(例如:使用某些云调度) 使用外部调度服务触发推送通知服务。据我了解,您的要求:
推送通知是服务器触发不是客户端请求
推送通知的要点是您应该在外部触发通知以避免使用最终用户设备上的资源。这不会阻止您从用户那里收集通知首选项,将此信息保存在外部,以便您可以在需要时从外部触发通知。
有关 PWA 通知的更多信息可以在以下文章中找到: https://developers.google.com/web/fundamentals/codelabs/push-notifications/
据我所知,PWA Service Worker 不应该使用计时器!
作为使用 PWA 通知的替代方法,您可能需要正确考虑使用不同的通知服务。例如 FCM https://firebase.google.com/docs/cloud-messaging/
这个想法可能是在外部保存用户的通知偏好,并在达到预定时间时通过另一个云服务触发 FCM 通知。
显然,只有当用户连接到网络时,这些通知才会起作用。然而,任何需要网络访问的通知服务也是如此。
我希望以上内容对您有所帮助,干杯并快乐编码!
【讨论】:
是否有严格意义上不是“推送通知”的桌面通知? 没有不会以某种方式引起问题的“桌面通知”。但是,如果费用合理,您可能需要考虑使用 FCM 通知和调度服务。两者都在您的应用程序之外。我已更新我的答案以涵盖您更新问题的这方面。【参考方案4】:假设您网站上的通知数据不会从服务器发送。使用本地存储将是可行的方法。
您可以存储一个变量来帮助跟踪在用户访问您的网站时何时显示通知:
localStorage.setItem("lastNotification", Date.now());
所以你可以有一个执行以下操作的脚本;
function notificationHelper()
var lastTime = localStorage.getItem("lastNotification");
if(Date.now - lastTime > 86400000)
//Logic to show notication here
//set a new time at the end of the logic
//Otherwise Do Nothing
【讨论】:
有没有办法保证这个函数在未来24小时执行?我了解简单的超时不起作用,因为服务人员已关闭。以上是关于如何在没有后端服务器的情况下在 24 小时后触发桌面通知?的主要内容,如果未能解决你的问题,请参考以下文章
我可以在没有自己的后端服务器的情况下在 React 中实现 Stripe 结账吗?
如何在没有触发器和手动插入的情况下在 mysql 中生成/自动增量 guid?
应该打字吗?如果不是,如何在不破坏用户的情况下在 npm install 上触发类型安装?