我正在使用 PHP 通过 VAPID 向浏览器发送推送通知。我正在使用网络推送库来实现这一点(https://github.com/web-push-libs/web-push-php),它对我来说工作得很好。 但问题是向 100000 多个用户发送推送通知非常耗时,而且还会降低服务器速度。
如何使用一个 API 调用一次向多个用户发送通知或一次向 1000 个用户发送通知?任何帮助将不胜感激
require __DIR__ . '/../vendor/autoload.php';
use Minishlink\WebPush\WebPush;
$subscription = json_decode(file_get_contents('php://input'), true);
$auth = array(
'VAPID' => array(
'subject' => 'https://www.example.com',
'publicKey' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'privateKey' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
),
);
$webPush = new WebPush($auth);
$res = $webPush->sendNotification(
"https://fcm.googleapis.com/fcm/send/xxxxxxxxxxxxxxxxxxxxxxxxxx",
"hello",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
true
);
Webpush 通知可能会消耗网络和 CPU 资源,但优化您的实现会有所帮助。升级到最新的库版本 (4.x),将内存限制增加到 500MB,将超时减少到 6 秒,并禁用 SSL 验证。这些调整可能允许您在 5-7 秒内发送大约 500 个网络推送。然而,对于更高的吞吐量,例如每分钟发送 100 万次 Web 推送,需要高级优化和利用多个服务器。
$push = new WebPush($authenticationData,[],6,['verify'=>false]);
ini_set('memory_limit', '500M');
如果您有数千名客户并且想要如此快地发送网络推送,我建议您在没有有效负载的情况下发送它,并且您可以在服务工作线程中获取有效负载。这样你就可以在一秒内发送 1000 个 webpush,而且速度非常快。
(向许多用户)发送带有有效负载的网络推送会花费大量的 cpu、ram 和网络资源。 (因为库必须为每个订阅者加密有效负载,并且必须将其一一发送给每个订阅者。带有有效负载的 webpush 没有批量发送选项。)
推送提供商对发送的每条消息都有限制(对于 Firebase,它是 500,我不确定)。因此,如果您需要发送给比这更多的用户,则必须将其分成块。
这是一个示例(C# 语言):
string response = string.Empty;
int pushNotificationLimit = 500;
int totalDevices = deviceTokens.Count();
if (totalDevices > pushNotificationLimit)
{
int sent = 0;
IEnumerable<DeviceVM> limitedDeviceTokens = null;
while (sent < totalDevices)
{
limitedDeviceTokens = deviceTokens.Skip(sent).Take(pushNotificationLimit);
response = response + await PushAsync(model, limitedDeviceTokens.Select(c => c.Token));
sent = sent + limitedDeviceTokens.Count();
}
}
else
{
response = response + await PushAsync(model, deviceTokens.Select(c => c.Token));
}
不过,强烈不建议这样做。出于安全性和可靠性原因,API 的请求超时时间应较短。
要发送广播消息,您应该寻址设备组: Firebase 设备组文档