如何使用 PHP 发送 Web 推送通知

在这里插入图片描述
Web Push API 允许您向 Web 浏览器和 API 发送推送通知。虽然大部分逻辑发生在浏览器中,但您仍然需要一个服务器端组件来生成通知。以下是使用 PHP 实现 Web 推送后端的方法。

先决条件

出于本教程的目的,我们假设您熟悉在 PHP 中创建 HTTP API 的基础知识。您需要使用 Web 框架公开一些公共端点。这些将由您的浏览器内 JavaScript 调用以注册和注销设备。

本文不会涉及浏览器端代码或其工作方式。您需要组合一个服务工作者来响应传入的推送事件并向用户显示通知。

概括地说,Web Push 流程如下所示:

  1. 在浏览器中注册了推送订阅。浏览器向您的 JavaScript 发出一个唯一的端点 URL。
  2. 您的 JavaScript 将订阅数据发送到您的服务器并识别它适用的用户。
  3. 当您的后端需要发送推送通知时,创建有效负载并将其发送到作为订阅数据的一部分报告的端点 URL。
  4. 用户的浏览器将通过供应商的通知传递平台接收有效载荷。您的 JavaScript 服务工作者处理后续事件并使用浏览器的通知 API 来提醒用户。

以下是如何实现步骤 1 到 3 的服务器端方面。

获取设置

我们将web-push通过 minishlink 使用 Packagist 包。这将与每个浏览器通知平台的交互抽象化,因此您不必手动区分端点类型。

使用 Composer 将包添加到您的项目中:

composer require minishlink/web-push

gmp要使用最新版本,您需要带有、mbstring、curl和openssl扩展名的 PHP 7.2 或更高版本。如果您必须使用较旧的 PHP 版本,请将包锁定到较早的版本以保持兼容性。

该库公开了一个核心WebPush类,其中包含允许您单独或批量发送通知的方法。订阅由类的实例表示Subscription。

提供 VAPID 密钥

对符合标准的 Web Push 生态系统的信任是通过使用VAPID 密钥来实现的。您的服务器需要一个 VAPID 密钥对,以便它可以对浏览器进行身份验证。公钥应通过 API 端点公开。

您可以使用包生成 VAPID 密钥集web-push:

use Minishlink\WebPush\VAPID;
 
$keyset = VAPID::createVapidKeys();
 
// public key - this needs to be accessible via an API endpoint
echo $keyset["publicKey"];
 
// private key - never expose this!
echo $keyset["privateKey"];
 
file_put_contents("vapid.json", json_encode($keyset));

为您的系统生成密钥并将它们存储到永久位置。添加一个 API 端点,以便您的客户端 JavaScript 可以检索公钥。这将用于设置浏览器的推送订阅。如果用户的设备已使用相应的 VAPID 私钥签名,则他们将接受传入的推送事件。

注册推送订阅

该序列的下一步是接收来自您的客户的推送订阅请求。一旦浏览器确认了新的推送订阅,您的 JavaScript 应该将订阅的端点 URL 和相关的身份验证密钥发送到您的服务器。将这些详细信息与用户 ID 一起存储,以便您稍后可以检索链接到该用户的所有推送注册设备。

我们省略了此步骤的代码示例,因为实现取决于您的数据存储层和您的 JavaScript 发送的值。通常,这将是PushSubscription对象的 JSON 表示。您需要一组简单的数据库支持的 CRUD API 端点来创建订阅、替换现有订阅以及在用户取消订阅时请求删除。

准备订阅

一旦客户成功注册,您就可以开始使用web-push库发送通知。首先创建一个WebPush类的实例:

use Minishlink\WebPush\WebPush;
 
$webPush = new WebPush([
    "VAPID" => [
        "subject" => "https://example.com",
        "publicKey" => "VAPID_Public_Key_Here",
        "privateKey" => "VAPID_Private_Key_Here"
    ]
]);

WebPush每次发送通知时,您都可以重复使用一个实例。该库需要使用您之前生成的 VAPID 密钥集进行配置。密钥应编码为 Base64,但如果您使用库创建它们,则会为您处理。

VAPIDsubject用于识别您的服务器及其联系方式。您可以提供网站 URL 或mailto:电子邮件地址链接。

接下来,您需要检索您将发送到的推送订阅。使用您的数据访问系统查找与您要发送到的用户关联的推送端点 URL。将每个订阅转换为一个Subscription实例:

use Minishlink\WebPush\Subscription;
 
// Get user's push data...
// SELECT * FROM push_subscriptions WHERE user_id = 123456
 
$subscription = Subscription::create([
    "endpoint" => "https://fcm.google.com/...",
    "contentEncoding" => "aesgcm",
    "authToken" => "<auth token from JavaScript PushSubscription object>"
    "keys" => [
        "auth" => "<auth token from JavaScript PushSubscription object>",
        "p256dh" => "<p256dh token from JavaScript PushSubscription object>"
    ]
]);

的auth属性PushSubscription重复两次,以应对浏览器服务使用的两个不同版本的规范。P256DH 属性是另一个公钥,在订阅设置时应提供。

该web-push库与 Chrome 和 Firefox 推送端点兼容。它还可以与任何其他符合当前标准的 Web 推送实现一起使用。

发送通知

现在结合您的WebPush和Subscription实例发送通知:

$result = $webPush -> sendOneNotification(
    $subscription,
    json_encode([
        "message" => "Demo notification",
        "foo" => "bar"
    ])
);

呼叫sendOneNotification()为单个通知提供即时交付。在这种情况下,有效负载是具有两个属性的 JSON 编码数组。这取决于您发送的数据和使用的格式——您的 JavaScript 客户端按原样接收数据并可以在必要时对其进行解释。

发送通知会返回一个结果类,让您检查操作是否成功:

if ($result -> isSuccess()) {
    // all good
}
else {
 
    // something went wrong
    error_log($result -> getReason());
 
    // provides raw HTTP response data
    error_log($result -> getResponse());
 
}

如果发生错误,您可以采取措施重试或取消交付。

通知订阅也可能过期。调用isSubscriptionExpired()结果类的方法以确定这是否是失败的原因。在这种情况下,您可以从数据库中删除订阅,确保您不会向死端点发送任何其他内容。

批处理通知

通知可以通过一个方法调用批量发送:

$webPush -> queueNotification($subscription, ["msg" => "first"]);
$webPush -> queueNotification($subscription, ["msg" => "second"]);
 
foreach ($webPush -> flush() as $i => $result) {
    echo ("Notification $i was " . ($result -> isSuccess() ? "sent" : "not sent"));
}

当您知道您将在短时间内发送大量通知时,这很有用。将所有有效负载排队并web-push以最佳方式交付它们。

flush()您可以通过将整数传递给方法来限制单个发送的通知数量:

$webPush -> flush(100);     // send 100 messages

默认值为1000。

通知选项

sendOneNotification()并queueNotification()接受以下选项作为第三个数组参数:

  • TTL–
    控制浏览器的通知平台在通知无法立即传递到用户设备时将保留多长时间。如果用户的设备处于离线状态,平台默认会在接下来的四个星期内尝试交付它。如果您要发送下周不相关的通知,请相应地调整 TTL,以便用户不会看到过时的内容。
  • urgency–接受normal,low或very-low作为值。一些平台可能会使用它来调整通知传递的频率。进入省电模式的设备可能会暂停发送非紧急通知。
  • batchSize– 这与上述论点具有相同的效果flush()。

您可以使用WebPush构造函数的第二个参数配置默认选项值:

$webPush = new WebPush(["VAPID" => [...]], ["TTL" => 3600]);

概括

该web-push库使使用 PHP 发送 Web 推送通知变得容易。您可以在各种浏览器平台上获得一个抽象层,支持批处理、错误处理和所有 Web 推送功能。

Web Push 机制是一种不寻常的浏览器系统,因为它依赖于您自己提供的远程服务器端组件。这可能使它看起来不透明和技术性。在实践中,创建一个简单的 PHP 后端既快速又容易;前端实现通常是更耗时的方面,特别是如果您还没有使用服务工作者功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mikes zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值