【问题标题】:Only show notifications if tab is closed仅在选项卡关闭时显示通知
【发布时间】:2022-01-10 19:52:14
【问题描述】:

我有一个 node.js 推送通知服务器(websocket 服务器也在上面运行),只要 websocket 服务器收到消息,它就会发送推送事件。这样做的问题是,无论发生什么,当 websocket 服务器收到一条消息时,它无论如何都会广播一条消息。虽然这很好,但对于活跃在网站上的客户来说,这可能会成为一个问题,因为通知是不必要的,因为人们已经可以看到发生了什么,并且 serviceworker 无法访问 DOM,因此它无法判断窗口是否打开与否。我尝试了navigator.serviceWorker.controller.postMessage 方法来告诉服务器“停止”通知服务,或者在下面的代码中“启动”通知服务。这一切似乎都是正确的,我没有收到任何错误,但它似乎不起作用,因为它会显示窗口是否打开的通知。

(main.js)

window.onload = function() {
    if (Notification.permission !== "granted") {
        Notification.requestPermission((permit)=>{
            console.log(permit);
        });
    }
    subscribe().catch(error => console.error(error));
    navigator.serviceWorker.controller.postMessage("stop"); //Tell serviceWorker to not show notifications
}
window.onbeforeunload = function() {
   navigator.serviceWorker.controller.postMessage("start"); //Tell serviceWorker that it is allowed show notifications
}
function urlBase64ToUint8Array(base64String) {const padding = '='.repeat((4 - base64String.length % 4) % 4);const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');const rawData = window.atob(base64);const outputArray = new Uint8Array(rawData.length);for (let i = 0; i < rawData.length; ++i) {outputArray[i] = rawData.charCodeAt(i);}return outputArray;}
const publicVapidKey = <key here>;
async function subscribe() {
    if ('serviceWorker' in navigator) {
        //register serviceworker
        const register = await navigator.serviceWorker.register('/sw.js', {
            scope: '/'
        });
        //subscribe to notifications
        const subscription = await register.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey: urlBase64ToUint8Array(publicVapidKey),
        });
        //send subscription to server
        await fetch('http://remoteserver.com:8080/subscribe', {
            method: 'POST',
            body: JSON.stringify(subscription),
            headers: {
                'Content-Type': 'application/json'
            }
        });
    } else {console.error('Service workers are not supported in this browser');}
}

(sw.js)

var allowed;
self.addEventListener('message', event => {
    if (event.data == "stop") {
        allowed = false;
    } else if (event.data == "start") {
        allowed = true;
    }
});
self.addEventListener('push', event => {
    if (allowed == true) {
        const data = event.data.json();
        self.registration.showNotification(data.title, {
            body: data.body,
            icon: data.icon
        });
    }
});

有人知道怎么回事吗?

【问题讨论】:

    标签: javascript dom conditional-statements service-worker web-push


    【解决方案1】:

    Service Worker 是您的客户端应用程序和服务器之间的中介。

    如果客户端被确定为处于活动状态(由您在代码中做出该决定 - 请参阅下面的链接),它应该与 sw 进行通信以通知它。

    您可以在 sw 和您的客户端(与 websockets 不同)之间实现一个心跳/乒乓球,如果客户端无法响应(或响应非“活动”的枚举) ,那么你的软件就会知道,并且可以做出适当的响应(无论是简单地不发出从服务器接收到的通知,还是完全取消订阅等)

    更多阅读:Page Visibility APIDocument.hasFocus()

    【讨论】:

      猜你喜欢
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多