qruto/laravel-wave

无需WebSockets即可实现流畅的Laravel广播和SSE。

0.9.1 2024-04-13 04:52 UTC

This package is auto-updated.

Last update: 2024-09-09 08:17:42 UTC


README

实时性 带到您的应用中

Build Status Styles check Types check Refactor code Total Downloads Latest Stable Version

介绍

使用 Wave 激活 Laravel 的 广播系统 的力量。想象一下,无需任何 WebSockets 设置,即可通过原生 HTTP 进行实时服务器广播。认识一下 服务器发送事件 🛜 它与 Laravel 的默认 redis 广播驱动程序无缝协作,并支持 Laravel Echo

通过我们的 演示流推文 🐤 亲身体验。

服务器发送事件 (SSE) 专门针对实时服务器到客户端通信进行了优化。

兼容

🌟 关键特性

⚡ 与原生 Redis 驱动程序协同工作:Wave 与 Laravel 的默认 redis 广播驱动程序无缝集成,确保高效的实时数据传输。

🔄 从上次中断处恢复:连接中断?没问题!Wave 智能地从上次事件恢复事件流,确保在传输过程中不会丢失关键数据。

🟢 实时模型:通过一个简单的界面,Wave 支持Laravel的本地约定进行 模型事件广播广播通知,从而以实时更新提升您的应用程序。

🍃 使用 pauseInactive 进行资源友好型广播:此功能通过在用户不活跃时(例如,当用户最小化浏览器时)关闭数据流,并在恢复可见性时自动重新打开它,从而最大限度地提高资源效率。默认关闭。

🎛️️ 完全请求控制:Wave 将连接和认证请求的控制权交给你,让你可以自由地根据您的确切需求塑造广播设置。

安装

Laravel 11 或更高版本

首先使用 Composer 安装包,然后安装广播设置

composer require qruto/laravel-wave
php artisan install:broadcasting

Laravel 10 或更低版本

使用 Composer 和 npm 在服务器和客户端上安装 Wave

composer require qruto/laravel-wave
npm install laravel-wave

然后,将您的 .env 文件设置为使用 redis 广播驱动程序

BROADCAST_DRIVER = redis

用法

安装 Wave 后,您的服务器即可广播事件。您可以使用它与 Echo 一样,或尝试使用 Wave 模型 API 与预定义的 Eloquent 事件一起工作。

在 Laravel 11 或更高版本中,在执行 install:broadcasting 后,您将在

  • routes/channels.php 中找到广播频道授权文件
  • config/broadcasting.php 中找到广播配置文件
  • resources/echo.js 中找到 Echo 实例
  • (可选)config/wave.php 中的 Wave 配置文件

手动使用

使用 WaveConnector 导入 Laravel Echo 并将其传递给广播器选项

import Echo from 'laravel-echo';

import { WaveConnector } from 'laravel-wave';

window.Echo = new Echo({broadcaster: WaveConnector});
对于 Laravel 10 或更低版本,在 resources/js/bootstrap.js 文件中定位 Echo 连接配置。
- import Echo from 'laravel-echo';

- import Pusher from 'pusher-js';
- window.Pusher = Pusher;

- window.Echo = new Echo({
-     broadcaster: 'pusher',
-     key: import.meta.env.VITE_PUSHER_APP_KEY,
-     wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
-     wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
-     wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
-     forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
-     enabledTransports: ['ws', 'wss'],
- });
+ import Echo from 'laravel-echo';

+ import { WaveConnector } from 'laravel-wave';

+ window.Echo = new Echo({ broadcaster: WaveConnector });

像平常一样使用 Echo。

📞 接收广播 文档。

使用 Live Eloquent 模型

使用 模型事件广播广播通知 的原生约定,您可以使用 Wave 模型接收模型事件和通知。

import { Wave } from 'laravel-wave';

window.Wave = new Wave();

wave.model('User', '1')
    .notification('team.invite', (notification) => {
        console.log(notification);
    })
    .updated((user) => console.log('user updated', user))
    .deleted((user) => console.log('user deleted', user))
    .trashed((user) => console.log('user trashed', user))
    .restored((user) => console.log('user restored', user))
    .updated('Team', (team) => console.log('team updated', team));

首先,在 Wave 实例上调用 model 方法,传入模型名称和键。

默认情况下,Wave 使用 App\Models 命名空间前缀模型名称。您可以使用 namespace 选项自定义此设置

window.Wave = new Wave({namespace: 'App.Path.Models'});

📄 查看完整的 Laravel 广播文档

配置

客户端选项

这些选项可以传递给 WaveEcho 实例

new Echo({
    broadcaster: WaveConnector,
    endpoint: '/sse-endpoint',
    bearerToken: 'bearer-token',
    //...
});

// or

new Wave({
    authEndpoint: '/custom-broadcasting/auth',
    csrfToken: 'csrf-token',
})

服务器选项

您可以使用以下方式发布 Wave 配置文件

php artisan vendor:publish --tag="wave-config"

以下是已发布配置文件的内容

return [

    /*
    |--------------------------------------------------------------------------
    | Resume Lifetime
    |--------------------------------------------------------------------------
    |
    | Define how long (in seconds) you wish an event stream to persist so it
    | can be resumed after a reconnect. The connection automatically
    | re-establishes with every closed response.
    |
    | * Requires a cache driver to be configured.
    |
    */
    'resume_lifetime' => 60,

    /*
    |--------------------------------------------------------------------------
    | Reconnection Time
    |--------------------------------------------------------------------------
    |
    | This value determines how long (in milliseconds) to wait before
    | attempting a reconnect to the server after a connection has been lost.
    | By default, the client attempts to reconnect immediately. For more
    | information, please refer to the Mozilla developer's guide on event
    | stream format.
    | https://mdn.org.cn/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format
    |
    */
    'retry' => null,

    /*
    |--------------------------------------------------------------------------
    | Ping
    |--------------------------------------------------------------------------
    |
    | A ping event is automatically sent on every SSE connection request if the
    | last event occurred before the set `frequency` value (in seconds). This
    | ensures the connection remains persistent.
    |
    | By setting the `eager_env` option, a ping event will be sent with each
    | request. This is useful for development or for applications that do not
    | frequently expect events. The `eager_env` option can be set as an `array` or `null`.
    |
    | For manual control of the ping event with the `sse:ping` command, you can
    | disable this option.
    |
    */
    'ping' => [
        'enable' => true,
        'frequency' => 30,
        'eager_env' => 'local', // null or array
    ],

    /*
    |--------------------------------------------------------------------------
    | Routes Path
    |--------------------------------------------------------------------------
    |
    | This path is used to register the necessary routes for establishing the
    | Wave connection, storing presence channel users, and handling simple whisper events.
    |
    */
    'path' => 'wave',

    /*
     |--------------------------------------------------------------------------
     | Route Middleware
     |--------------------------------------------------------------------------
     |
     | Define which middleware Wave should assign to the routes that it registers.
     | You may modify these middleware as needed. However, the default value is
     | typically sufficient.
     |
     */
    'middleware' => [
        'web',
    ],

    /*
     |--------------------------------------------------------------------------
     | Auth & Guard
     |--------------------------------------------------------------------------
     |
     | Define the default authentication middleware and guard type for
     | authenticating users for presence channels and whisper events.
     |
     */
    'auth_middleware' => 'auth',

    'guard' => 'web',

];

使用 Nginx + PHP FPM 的持久连接

Wave 被设计为在请求超时时自动重新连接。在重新连接期间,您不会丢失任何事件,因为 Wave 默认存储事件历史一分钟并从中恢复。您可以通过修改配置文件中的 resume_lifetime 值来调整事件历史存储的持续时间。

但是,如果您想保持持久连接,让我们配置您的 web 服务器。

fastcgi_read_timeout

默认情况下,对于 Nginx + PHP FastCGI 服务器设置,fastcgi_read_timeout 的值是 60s

选项 1. 不更改 fastcgi_read_timeout

确保推送到 Wave 连接的事件之间的间隔短于读取超时值

为了提高事件发生频率高于标准超时的确定性,Wave 会尝试在每次 Server-Sent Events (SSE) 连接请求中发送一个 ping 事件,前提是上一个事件在 ping.frequency 配置值之前发生。

如果您的应用程序不需要很多实时连接,指定在每次 Wave 连接中发送 ping 事件的列表。默认情况下,此值设置为 local

选项 2. 手动 ping 控制

为了确保准确发送 ping 事件频率

  1. 通过将 ping.enable 配置值更改为 false 禁用自动发送
  2. 使用 sse:ping 命令手动发送单个 ping 或以间隔操作

使用 --interval 选项运行命令,以指定的秒数间隔发送 ping 事件,例如让我们每 30s 发送一次 ping 事件

php artisan sse:ping --interval=30

因此,每 30s,该命令将向所有活动连接发送 ping 事件,并确保连接保持持久,因为事件发送频率小于 60s

或者,使用 Laravel 的 任务调度器 每分钟或更频繁地发送 ping 事件,如果 fastcgi_read_timeout 值大于 60s

protected function schedule(Schedule $schedule)
{
    $schedule->command('sse:ping')->everyMinute();
}

request_terminate_timeout

某些平台,如 Laravel Forge,使用 request_terminate_timeout = 60 配置 PHP FPM 池,在 60 秒后终止所有请求。

您可以在 /etc/php/8.1/fpm/pool.d/www.conf 配置文件中禁用此设置

request_terminate_timeout = 0

或者您可以配置一个单独的池来用于SSE连接。

未来计划

📍 本地广播驱动程序

📥 📤 双向实时模型同步

📡 开放实时能力后的一些很酷的事情...

测试

composer test

支持

鉴于乌克兰最近发生的事件,我的生活发生了意想不到的转变。自2月24日起,我失去了我的商业工作、我的永久居留权以及规划未来的能力。

在这些充满挑战的日子里,我从创建开源项目,如Wave,中获得了力量和目标。

support me

欢迎您访问我的GitHub赞助页面。在那里,您可以了解更多关于我的当前工作、未来抱负和愿望。您每给一颗星,都会让我的一天更加愉快,您的赞助可以在我继续创作的能力上产生深远的影响。

我真诚地感谢您的支持,无论是呼吁还是发自内心的“谢谢”。

💳 直接帮助

变更日志

请参阅变更日志以获取有关最近更改的更多信息。

贡献

请参阅贡献指南以获取详细信息。

安全漏洞

请参阅我们的安全策略了解如何报告安全漏洞。

致谢

基于Spatie Laravel 骨架的包模板。

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。