我使用 stripe 进行付款,并为事件设置了 webhook。 - 如果客户的信用卡过期并且输入了新的付款信息,Stripe 会自动重试失败的订阅,并发送一个 Webhook 以显示订阅续订是否失败或成功。 我喜欢根据续订状态更新前端,续订状态可能会在付款信息更新后几秒钟内出现。 - 有没有办法让 Inertia 重新请求数据并从 webhook 重新渲染前端 - 而不是从用户请求?
你应该看看 Laravel 的广播功能。
InertiaJs v2 现在有 polling,它将帮助您监听数据库更改,但我认为这不是一个好方法,因为您将无限期地轮询页面以获取更改(除非您手动停止它)。人们很可能只会支付一次,因此轮询并不是一个好的解决方案,过度杀伤力,并且进行一次 UI 更新也不是轮询的良好用例。
我想事件侦听器可以将侦听器的处理方法中的事件广播作为后台任务来处理,然后向它们显示一条消息并在前端组件中添加一个观察器以显示更新的数据。它使用 Echo.js,因此您可以在 JavaScript 中收听广播。
我从 Laravel 的广播文档页面复制了以下示例:
例如,假设您的应用程序能够导出用户的数据 保存为 CSV 文件并通过电子邮件发送给他们。但是,创建此 CSV 文件 需要几分钟,因此您选择在以下时间内创建并邮寄 CSV 排队的作业。创建 CSV 并将其邮寄给用户后,我们 可以使用事件广播来调度 App\Events\UserDataExported 我们应用程序的 JavaScript 接收到的事件。一旦活动 收到后,我们可以向用户显示一条消息,表明他们的 CSV 已包含 已通过电子邮件发送给他们,而他们无需刷新页面。
您首先要安装 Laravel Reverb:
composer require laravel/reverb
然后创建实现 ShouldBroadcast 接口的事件类:
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MyEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $user;
public function __construct($user)
{
$this->user = $user;
}
public function broadcastOn()
{
return new Channel('my-channel-name');
}
}
然后,您可以从事件侦听器广播该事件;
namespace App\Listeners;
use App\Events\MyEvent;
use Laravel\Paddle\Cashier; // I'm using Paddle in my app
use Laravel\Paddle\Events\WebhookReceived;
class UpdateUserListener
{
public function handle(WebhookReceived $event)
{
// Your listener logic here, such as updating the user's purchased products or subscriptions
// Broadcast the event
broadcast(new MyEvent($event->user))->toOthers();
}
}
只需在
config/reverb.php
文件中检查 Laravel Reverb 配置是否满足您的需求
然后在客户端,您应该使用 Echo 监听事件:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Echo = new Echo({
broadcaster: 'reverb',
key: 'your-reverb-key',
wsHost: window.location.hostname,
wsPort: 8080,
forceTLS: false,
disableStats: true,
});
Echo.channel('my-channel-name')
.listen('MyEvent', (event) => {
console.log(event);
});