javascript - 通过一次通话向所有订阅者发送网络推送通知

标签 javascript node.js push-notification web-push

我正在我的网站中与服务人员一起实现网络推送通知。我有一个工作网站,每小时都会发布新工作。我想在新职位发布时通知订阅者。 我已经完成了让用户订阅和写入 Node 服务器的实现,以及通过生成 VAPID key 发送推送通知。

我有一个问题,我觉得当我需要向所有订阅者发送推送通知时,我是否需要为每个用户发送新的调用,或者有某种机制可以在一次调用中将其发送给所有订阅者。

例如,如果我有 100,000 个订阅者,那么我是否需要调用 100,000 个电话,还是有其他方法可以发送 1 个电话并一次性通知所有 100,000 个订阅者有关新职位更新的信息?

我确实觉得如果我一次性发送数千个调用,我会被相关浏览器服务限制。

有没有一种方法可以通过一次调用来完成?

这是我当前从快速服务器向所有订阅者发送通知的代码路线。

const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Subscription = mongoose.model('subscribers');
const q = require('q');
const webPush = require('web-push');
const keys = require('./../config/keys');
router.post('/', (req, res) => {
    const payload = {
        title: req.body.title,
        message: req.body.message,
        url: req.body.url,
        ttl: req.body.ttl,
        icon: req.body.icon,
        image: req.body.image,
        badge: req.body.badge,
        tag: req.body.tag
    };

Subscription.find({}, (err, subscriptions) => {
    if (err) {
        console.error(`Error occurred while getting subscriptions`);
        res.status(500).json({
            error: 'Technical error occurred'
        });
    } else {
        let parallelSubscriptionCalls = subscriptions.map((subscription) => {
            return new Promise((resolve, reject) => {
                const pushSubscription = {
                    endpoint: subscription.endpoint,
                    keys: {
                        p256dh: subscription.keys.p256dh,
                        auth: subscription.keys.auth
                    }
                };

                const pushPayload = JSON.stringify(payload);
                const pushOptions = {
                    vapidDetails: {
                        subject: 'http://example.com',
                        privateKey: keys.privateKey,
                        publicKey: keys.publicKey
                    },
                    TTL: payload.ttl,
                    headers: {}
                };
                webPush.sendNotification(
                    pushSubscription,
                    pushPayload,
                    pushOptions
                ).then((value) => {
                    resolve({
                        status: true,
                        endpoint: subscription.endpoint,
                        data: value
                    });
                }).catch((err) => {
                    reject({
                        status: false,
                        endpoint: subscription.endpoint,
                        data: err
                    });
                });
            });
        });
        q.allSettled(parallelSubscriptionCalls).then((pushResults) => {
            console.info(pushResults);
        });
        res.json({
            data: 'Push triggered'
        });
    }
});

});

router.get('/', (req, res) => {
    res.json({
        data: 'Invalid Request Bad'
    });
});
module.exports = router;

最佳答案

当前网络推送标准不允许向多个收件人发送相同的通知:如果您直接使用浏览器推送服务,则需要为每个收件人进行不同的调用。

我已经在 2016 年在官方 Github 存储库上问过这个问题: https://github.com/w3c/push-api/issues/208

如果您想卸载应用程序,您可以使用推送服务来代表您完成这项工作:然后您对推送服务进行一次 API 调用,它就会对浏览器推送服务进行数千次调用。

对于限制,目前我还没有看到任何问题,即使每小时有数百万条通知。

关于javascript - 通过一次通话向所有订阅者发送网络推送通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58446241/

相关文章:

javascript - 使用 moment 获取日期和当前日期之间的时间差

node.js - 将函数从模块导入到 Coffeescript 中的全局命名空间?

javascript - 扩展 Joi 未实现自定义运算符

jquery - 将鼠标悬停在 nightwatchjs 中的链接上

android - GCM 生产准备好了吗?我们现在应该开始使用它吗?

javascript - 使用 jquery 和常规 javascript 使用不允许媒体查询样式表的 CMS 打开 Div 的打印窗口

javascript - Node.js:任何错误都会导致 Heroku 服务器崩溃

ios - React native ios 处理推送通知无需点击通知

ios - OneSignal 如何决定使用哪个 p12 文件(开发或分发)?

javascript - react 条件渲染,在渲染中返回数组, react 16