如何一次向 100000 多个用户发送带有负载的 WebPush

问题描述 投票:0回答:2

我正在使用 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    
);
php push-notification
2个回答
0
投票

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 没有批量发送选项。)


0
投票

推送提供商对发送的每条消息都有限制(对于 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 设备组文档

© www.soinside.com 2019 - 2024. All rights reserved.