一次通话向所有订阅者发送网络推送通知
Posted
技术标签:
【中文标题】一次通话向所有订阅者发送网络推送通知【英文标题】:Send web push notification to all subscribers in one call 【发布时间】:2019-10-18 07:49:02 【问题描述】:我正在我的网站中使用服务人员实现网络推送通知。我有一个工作网站,每隔一小时就会发布新工作。我想在发布新工作时通知订阅者。 我已经完成了让用户订阅和编写节点服务器以及通过生成 VAPID 密钥来发送推送通知的实现。
我有一个问题,我觉得当我需要向所有订阅者发送推送通知时,我是否需要为每个用户发送新呼叫,或者有某种机制可以在一次呼叫中将其发送给所有订阅者。
例如,如果我有 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;
【问题讨论】:
【参考方案1】:目前,网络推送标准不允许向多个收件人发送相同的通知:如果您直接处理浏览器推送服务,则需要为每个收件人拨打不同的电话。
我已经在 2016 年的 Github 官方仓库中问过这个问题: https://github.com/w3c/push-api/issues/208
如果您想卸载您的应用程序,您可以使用推送服务来代表您完成这项工作:然后您对推送服务进行一次 API 调用,它会向浏览器推送服务进行数千次调用。
对于目前的限制,我没有发现任何问题,即使每小时有几百万条通知。
【讨论】:
感谢@collionmacro 的留言。现在我明白了为什么它不能通过单个请求来完成,因为它是协议的一部分。我现在要么使用单独的机器发送通知,因为我有大量的用户将订阅。【参考方案2】:如果您只想进行一次 API 调用,可以使用 Firebase。您可以只为您的用户订阅一个“主题”,然后对 FCM 端点进行一次 API 调用,在请求正文中指定该主题,然后让 Google 处理所有工作以向您的订阅者发送推送通知。您也可以在您的 firabase 项目中使用您当前的 VAPID 密钥。
【讨论】:
已经这样做了。现在使用 firebase 向主题的所有成员发送通知。无论如何感谢您的回复。以上是关于一次通话向所有订阅者发送网络推送通知的主要内容,如果未能解决你的问题,请参考以下文章