qruto / laravel-wave
无需WebSockets即可实现流畅的Laravel广播和SSE。
Requires
- php: ^8.1
- illuminate/broadcasting: ^10.0|^11.0.6
- illuminate/console: ^10.0|^11.0.6
- illuminate/contracts: ^10.0|^11.0.6
- illuminate/http: ^10.0|^11.0.6
- illuminate/queue: ^10.0|^11.0.6
- illuminate/routing: ^10.0|^11.0.6
- laravel/prompts: ^0.1.16
- spatie/laravel-package-tools: ^1.14.1
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.14
- m6web/redis-mock: v5.6
- nunomaduro/collision: ^7.10|^8.1
- orchestra/testbench: ^8.14|^9.0
- pestphp/pest: ^v2.34
- pestphp/pest-plugin-laravel: ^2.3.0
- pestphp/pest-plugin-watch: ^2.1.0
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3.10
- rector/rector: ^0.19
- spatie/laravel-ray: ^1.35
README
将 实时性 带到您的应用中
介绍
使用 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'});
配置
客户端选项
这些选项可以传递给 Wave
或 Echo
实例
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 事件频率
- 通过将
ping.enable
配置值更改为false
禁用自动发送 - 使用
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,中获得了力量和目标。
欢迎您访问我的GitHub赞助页面。在那里,您可以了解更多关于我的当前工作、未来抱负和愿望。您每给一颗星,都会让我的一天更加愉快,您的赞助可以在我继续创作的能力上产生深远的影响。
我真诚地感谢您的支持,无论是呼吁还是发自内心的“谢谢”。
💳 直接帮助。
变更日志
请参阅变更日志以获取有关最近更改的更多信息。
贡献
请参阅贡献指南以获取详细信息。
安全漏洞
请参阅我们的安全策略了解如何报告安全漏洞。
致谢
基于Spatie Laravel 骨架的包模板。
许可证
MIT许可证(MIT)。请参阅许可证文件以获取更多信息。