广播
- Introduction
- Quickstart
- Server Side Installation
- Client Side Installation
- Concept Overview
- Defining Broadcast Events
- Authorizing Channels
- Broadcasting Events
- Receiving Broadcasts
- Presence Channels
- Model Broadcasting
- Client Events
- Notifications
介绍
在许多现代 Web 应用中,WebSocket 用于实现实时更新的用户界面。当服务器上的数据更新时,通常会通过 WebSocket 连接发送一条消息,供客户端处理。WebSocket 提供了一种更高效的替代方案,无需持续轮询应用服务器以获取应反映在 UI 中的数据更改。
例如,假设您的应用程序能够将用户数据导出到 CSV 文件并通过电子邮件发送给他们。但是,创建此 CSV 文件需要几分钟时间,因此您选择在队列作业中创建并邮寄 CSV 文件。当 CSV 文件创建完成并邮寄给用户后,我们可以使用事件广播来调度一个App\Events\UserDataExported
事件,该事件会被应用程序的 JavaScript 接收。接收到该事件后,我们可以向用户显示一条消息,告知他们 CSV 文件已通过电子邮件发送给他们,而无需用户刷新页面。
为了帮助您构建这些类型的功能,Laravel 可以轻松地通过 WebSocket 连接“广播”服务器端 Laravel事件。广播 Laravel 事件允许您在服务器端 Laravel 应用程序和客户端 JavaScript 应用程序之间共享相同的事件名称和数据。
广播背后的核心概念很简单:客户端连接到前端的指定频道,而你的 Laravel 应用程序将事件广播到后端的这些频道。这些事件可以包含你希望提供给前端的任何其他数据。
支持的驱动程序
默认情况下,Laravel 包含三个服务器端广播驱动程序供您选择:Laravel Reverb,Pusher Channels和Ably。
在深入研究事件广播之前,请确保您已阅读 Laravel 关于事件和监听器的文档。
快速入门
默认情况下,新的 Laravel 应用程序中不启用广播。你可以使用install:broadcasting
Artisan 命令启用广播:
1php artisan install:broadcasting
该install:broadcasting
命令会Prompts您选择要使用的事件广播服务。此外,它还会创建config/broadcasting.php
配置文件以及routes/channels.php
用于注册应用程序广播授权路由和回调的文件。
Laravel 支持多种开箱即用的广播驱动程序:Laravel Reverb、Pusher Channels、Ably以及log
用于本地开发和调试的驱动程序。此外,null
还包含一个驱动程序,允许您在测试期间禁用广播。配置文件中为每个驱动程序都提供了相应的配置示例config/broadcasting.php
。
应用程序的所有事件广播配置都存储在config/broadcasting.php
配置文件中。如果您的应用程序中不存在此文件,请不要担心;它会在您运行install:broadcasting
Artisan 命令时创建。
后续步骤
启用事件广播后,您就可以了解有关定义广播事件和监听事件的更多信息。如果您使用的是 Laravel 的 React 或 Vue入门套件,则可以使用 Echo 的useEcho 钩子来监听事件。
在广播任何事件之前,您应该首先配置并运行队列工作器。所有事件广播均通过队列作业完成,因此应用程序的响应时间不会受到广播事件的严重影响。
服务器端安装
要开始使用 Laravel 的事件广播,我们需要在 Laravel 应用程序中进行一些配置并安装一些包。
事件广播由服务器端的广播驱动程序完成,该驱动程序会广播您的 Laravel 事件,以便 Laravel Echo(一个 JavaScript 库)可以在浏览器客户端中接收它们。别担心 - 我们将逐步介绍安装过程的每个部分。
Reverb
要在使用 Reverb 作为事件广播器时快速启用 Laravel 的广播功能,请install:broadcasting
使用该选项调用 Artisan 命令。此 Artisan 命令将安装 Reverb 所需的 Composer 和 NPM 软件包,并使用相应的变量--reverb
更新应用程序文件:.env
1php artisan install:broadcasting --reverb
手动安装
运行该install:broadcasting
命令时,系统将Prompts你安装Laravel Reverb。当然,你也可以使用 Composer 包管理器手动安装 Reverb :
1composer require laravel/reverb
安装软件包后,您可以运行 Reverb 的安装命令来发布配置,添加 Reverb 所需的环境变量,并在应用程序中启用事件广播:
1php artisan reverb:install
您可以在Reverb 文档中找到详细的 Reverb 安装和使用说明。
推进器通道
要在使用 Pusher 作为事件广播器的同时快速启用 Laravel 的广播功能,请install:broadcasting
使用该--pusher
选项调用 Artisan 命令。此 Artisan 命令将Prompts您输入 Pusher 凭据,安装 Pusher PHP 和 JavaScript SDK,并.env
使用相应的变量更新应用程序文件:
1php artisan install:broadcasting --pusher
手动安装
要手动安装 Pusher 支持,您应该使用 Composer 包管理器安装 Pusher Channels PHP SDK:
1composer require pusher/pusher-php-server
接下来,您应该在配置文件中配置 Pusher Channels 凭证config/broadcasting.php
。此文件中已包含 Pusher Channels 配置示例,可让您快速指定密钥、机密和应用程序 ID。通常,您应该在应用程序的.env
文件中配置 Pusher Channels 凭证:
1PUSHER_APP_ID="your-pusher-app-id"2PUSHER_APP_KEY="your-pusher-key"3PUSHER_APP_SECRET="your-pusher-secret"4PUSHER_HOST=5PUSHER_PORT=4436PUSHER_SCHEME="https"7PUSHER_APP_CLUSTER="mt1"
该config/broadcasting.php
文件的pusher
配置还允许您指定options
Channels 支持的其他内容,例如集群。
然后,在应用程序的文件中将BROADCAST_CONNECTION
环境变量设置为:pusher
.env
1BROADCAST_CONNECTION=pusher
最后,您已准备好安装和配置Laravel Echo,它将在客户端接收广播事件。
巧妙地
以下文档讨论了如何在“推送器兼容”模式下使用 Ably。不过,Ably 团队推荐并维护了一个能够充分利用 Ably 独特功能的广播器和 Echo 客户端。有关使用 Ably 维护的驱动程序的更多信息,请参阅 Ably 的 Laravel 广播器文档。
要在使用Ably作为事件广播器的同时快速启用 Laravel 的广播功能,请install:broadcasting
使用选项调用 Artisan 命令--ably
。此 Artisan 命令将Prompts您输入 Ably 凭据,安装 Ably PHP 和 JavaScript SDK,并.env
使用相应的变量更新应用程序文件:
1php artisan install:broadcasting --ably
在继续操作之前,您需要在 Ably 应用程序设置中启用 Pusher 协议支持。您可以在 Ably 应用程序设置面板的“协议适配器设置”部分中启用此功能。
手动安装
要手动安装 Ably 支持,您应该使用 Composer 包管理器安装 Ably PHP SDK:
1composer require ably/ably-php
接下来,您应该在config/broadcasting.php
配置文件中配置您的 Ably 凭据。此文件中已包含一个 Ably 配置示例,可让您快速指定密钥。通常,此值应通过ABLY_KEY
环境变量设置:
1ABLY_KEY=your-ably-key
然后,在应用程序的文件中将BROADCAST_CONNECTION
环境变量设置为:ably
.env
1BROADCAST_CONNECTION=ably
最后,您已准备好安装和配置Laravel Echo,它将在客户端接收广播事件。
客户端安装
Reverb
Laravel Echo是一个 JavaScript 库,它可以轻松订阅频道并监听服务器端广播驱动程序广播的事件。
通过 Artisan 命令安装 Laravel Reverb 时install:broadcasting
,Reverb 和 Echo 的脚手架和配置将自动注入到你的应用程序中。但是,如果你希望手动配置 Laravel Echo,可以按照以下说明进行操作。
手动安装
要为应用程序的前端手动配置 Laravel Echo,请首先安装该pusher-js
软件包,因为 Reverb 使用 Pusher 协议进行 WebSocket 订阅、频道和消息:
1npm install --save-dev laravel-echo pusher-js
resources/js/bootstrap.js
安装 Echo 后,您就可以在应用程序的 JavaScript 中创建一个新的 Echo 实例了。执行此操作的最佳位置是Laravel 框架自带文件的底部:
1import Echo from 'laravel-echo'; 2 3import Pusher from 'pusher-js'; 4window.Pusher = Pusher; 5 6window.Echo = new Echo({ 7 broadcaster: 'reverb', 8 key: import.meta.env.VITE_REVERB_APP_KEY, 9 wsHost: import.meta.env.VITE_REVERB_HOST,10 wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,11 wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,12 forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',13 enabledTransports: ['ws', 'wss'],14});
1import { configureEcho } from "@laravel/echo-react"; 2 3configureEcho({ 4 broadcaster: "reverb", 5 // key: import.meta.env.VITE_REVERB_APP_KEY, 6 // wsHost: import.meta.env.VITE_REVERB_HOST, 7 // wsPort: import.meta.env.VITE_REVERB_PORT, 8 // wssPort: import.meta.env.VITE_REVERB_PORT, 9 // forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',10 // enabledTransports: ['ws', 'wss'],11});
1import { configureEcho } from "@laravel/echo-vue"; 2 3configureEcho({ 4 broadcaster: "reverb", 5 // key: import.meta.env.VITE_REVERB_APP_KEY, 6 // wsHost: import.meta.env.VITE_REVERB_HOST, 7 // wsPort: import.meta.env.VITE_REVERB_PORT, 8 // wssPort: import.meta.env.VITE_REVERB_PORT, 9 // forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',10 // enabledTransports: ['ws', 'wss'],11});
接下来,您应该编译应用程序的资产:
1npm run build
Laravel Echoreverb
广播器需要 laravel-echo v1.16.0+。
推进器通道
Laravel Echo是一个 JavaScript 库,它可以轻松订阅频道并监听服务器端广播驱动程序广播的事件。
通过install:broadcasting --pusher
Artisan 命令安装广播支持时,Pusher 和 Echo 的脚手架和配置将自动注入到你的应用程序中。但是,如果你希望手动配置 Laravel Echo,可以按照以下说明进行操作。
手动安装
要为应用程序的前端手动配置 Laravel Echo,首先安装laravel-echo
和pusher-js
包,它们利用 Pusher 协议进行 WebSocket 订阅、频道和消息:
1npm install --save-dev laravel-echo pusher-js
安装 Echo 后,您就可以在应用程序resources/js/bootstrap.js
文件中创建一个新的 Echo 实例:
1import Echo from 'laravel-echo'; 2 3import Pusher from 'pusher-js'; 4window.Pusher = Pusher; 5 6window.Echo = new Echo({ 7 broadcaster: 'pusher', 8 key: import.meta.env.VITE_PUSHER_APP_KEY, 9 cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,10 forceTLS: true11});
1import { configureEcho } from "@laravel/echo-react"; 2 3configureEcho({ 4 broadcaster: "pusher", 5 // key: import.meta.env.VITE_PUSHER_APP_KEY, 6 // cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER, 7 // forceTLS: true, 8 // wsHost: import.meta.env.VITE_PUSHER_HOST, 9 // wsPort: import.meta.env.VITE_PUSHER_PORT,10 // wssPort: import.meta.env.VITE_PUSHER_PORT,11 // enabledTransports: ["ws", "wss"],12});
1import { configureEcho } from "@laravel/echo-vue"; 2 3configureEcho({ 4 broadcaster: "pusher", 5 // key: import.meta.env.VITE_PUSHER_APP_KEY, 6 // cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER, 7 // forceTLS: true, 8 // wsHost: import.meta.env.VITE_PUSHER_HOST, 9 // wsPort: import.meta.env.VITE_PUSHER_PORT,10 // wssPort: import.meta.env.VITE_PUSHER_PORT,11 // enabledTransports: ["ws", "wss"],12});
接下来,您应该在应用程序文件中为 Pusher 环境变量定义适当的值.env
。如果文件中尚不存在这些变量.env
,则应添加它们:
1PUSHER_APP_ID="your-pusher-app-id" 2PUSHER_APP_KEY="your-pusher-key" 3PUSHER_APP_SECRET="your-pusher-secret" 4PUSHER_HOST= 5PUSHER_PORT=443 6PUSHER_SCHEME="https" 7PUSHER_APP_CLUSTER="mt1" 8 9VITE_APP_NAME="${APP_NAME}"10VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"11VITE_PUSHER_HOST="${PUSHER_HOST}"12VITE_PUSHER_PORT="${PUSHER_PORT}"13VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"14VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
根据应用程序的需求调整 Echo 配置后,您可以编译应用程序的资产:
1npm run build
使用现有的客户端实例
如果您已经有一个预先配置的 Pusher Channels 客户端实例并希望 Echo 使用,您可以通过client
配置选项将其传递给 Echo:
1import Echo from 'laravel-echo'; 2import Pusher from 'pusher-js'; 3 4const options = { 5 broadcaster: 'pusher', 6 key: import.meta.env.VITE_PUSHER_APP_KEY 7} 8 9window.Echo = new Echo({10 ...options,11 client: new Pusher(options.key, options)12});
巧妙地
以下文档讨论了如何在“推送器兼容”模式下使用 Ably。不过,Ably 团队推荐并维护了一个能够充分利用 Ably 独特功能的广播器和 Echo 客户端。有关使用 Ably 维护的驱动程序的更多信息,请参阅 Ably 的 Laravel 广播器文档。
Laravel Echo是一个 JavaScript 库,它可以轻松订阅频道并监听服务器端广播驱动程序广播的事件。
通过install:broadcasting --ably
Artisan 命令安装广播支持时,Ably 和 Echo 的脚手架和配置将自动注入到您的应用程序中。但是,如果您希望手动配置 Laravel Echo,可以按照以下说明进行操作。
手动安装
要为应用程序的前端手动配置 Laravel Echo,首先安装laravel-echo
和pusher-js
包,它们利用 Pusher 协议进行 WebSocket 订阅、频道和消息:
1npm install --save-dev laravel-echo pusher-js
在继续操作之前,您需要在 Ably 应用程序设置中启用 Pusher 协议支持。您可以在 Ably 应用程序设置面板的“协议适配器设置”部分中启用此功能。
安装 Echo 后,您就可以在应用程序resources/js/bootstrap.js
文件中创建一个新的 Echo 实例:
1import Echo from 'laravel-echo'; 2 3import Pusher from 'pusher-js'; 4window.Pusher = Pusher; 5 6window.Echo = new Echo({ 7 broadcaster: 'pusher', 8 key: import.meta.env.VITE_ABLY_PUBLIC_KEY, 9 wsHost: 'realtime-pusher.ably.io',10 wsPort: 443,11 disableStats: true,12 encrypted: true,13});
1import { configureEcho } from "@laravel/echo-react"; 2 3configureEcho({ 4 broadcaster: "ably", 5 // key: import.meta.env.VITE_ABLY_PUBLIC_KEY, 6 // wsHost: "realtime-pusher.ably.io", 7 // wsPort: 443, 8 // disableStats: true, 9 // encrypted: true,10});
1import { configureEcho } from "@laravel/echo-vue"; 2 3configureEcho({ 4 broadcaster: "ably", 5 // key: import.meta.env.VITE_ABLY_PUBLIC_KEY, 6 // wsHost: "realtime-pusher.ably.io", 7 // wsPort: 443, 8 // disableStats: true, 9 // encrypted: true,10});
您可能已经注意到我们的 Ably Echo 配置引用了一个VITE_ABLY_PUBLIC_KEY
环境变量。该变量的值应该是您的 Ably 公钥。您的公钥是 Ably 密钥中:
字符之前的部分。
根据您的需要调整 Echo 配置后,您可以编译应用程序的资产:
1npm run dev
概念概述
Laravel 的事件广播功能允许您使用基于驱动程序的 WebSocket 方法将服务器端 Laravel 事件广播到客户端 JavaScript 应用程序。目前,Laravel 已集成Laravel Reverb、Pusher Channels和Ably驱动程序。您可以使用Laravel Echo JavaScript 包在客户端轻松使用这些事件。
事件通过“频道”进行广播,频道可以指定为公共频道或私有频道。任何访问您应用的访客都可以订阅公共频道,无需任何身份验证或授权;但是,要订阅私有频道,用户必须经过身份验证并获得授权才能收听该频道。
使用示例应用程序
在深入研究事件广播的每个组件之前,让我们以电子商务商店为例进行高层次的概述。
在我们的应用中,假设有一个页面允许用户查看订单的配送状态。同时假设OrderShipmentStatusUpdated
当应用处理配送状态更新时会触发一个事件:
1use App\Events\OrderShipmentStatusUpdated;2 3OrderShipmentStatusUpdated::dispatch($order);
界面ShouldBroadcast
当用户查看订单时,我们不希望他们刷新页面来查看状态更新。相反,我们希望在订单创建时就将更新广播到应用程序。因此,我们需要OrderShipmentStatusUpdated
用ShouldBroadcast
接口标记该事件。这将指示 Laravel 在触发该事件时广播该事件:
1<?php 2 3namespace App\Events; 4 5use App\Models\Order; 6use Illuminate\Broadcasting\Channel; 7use Illuminate\Broadcasting\InteractsWithSockets; 8use Illuminate\Broadcasting\PresenceChannel; 9use Illuminate\Contracts\Broadcasting\ShouldBroadcast;10use Illuminate\Queue\SerializesModels;11 12class OrderShipmentStatusUpdated implements ShouldBroadcast13{14 /**15 * The order instance.16 *17 * @var \App\Models\Order18 */19 public $order;20}
该ShouldBroadcast
接口要求我们的事件定义一个broadcastOn
方法。此方法负责返回事件应在其上广播的频道。此方法的空存根已在生成的事件类中定义,因此我们只需填写其详细信息。我们只希望订单的创建者能够查看状态更新,因此我们将在与订单绑定的私有频道上广播该事件:
1use Illuminate\Broadcasting\Channel; 2use Illuminate\Broadcasting\PrivateChannel; 3 4/** 5 * Get the channel the event should broadcast on. 6 */ 7public function broadcastOn(): Channel 8{ 9 return new PrivateChannel('orders.'.$this->order->id);10}
如果您希望该事件在多个频道上广播,您可以返回array
:
1use Illuminate\Broadcasting\PrivateChannel; 2 3/** 4 * Get the channels the event should broadcast on. 5 * 6 * @return array<int, \Illuminate\Broadcasting\Channel> 7 */ 8public function broadcastOn(): array 9{10 return [11 new PrivateChannel('orders.'.$this->order->id),12 // ...13 ];14}
授权渠道
请记住,用户必须获得授权才能监听私人频道。我们可以在应用程序routes/channels.php
文件中定义频道授权规则。在此示例中,我们需要验证任何尝试监听私人orders.1
频道的用户是否确实是订单的创建者:
1use App\Models\Order;2use App\Models\User;3 4Broadcast::channel('orders.{orderId}', function (User $user, int $orderId) {5 return $user->id === Order::findOrNew($orderId)->user_id;6});
该channel
方法接受两个参数:频道名称和返回true
或false
指示用户是否有权在该频道上收听的回调。
所有授权回调都会接收当前已验证的用户作为其第一个参数,并将任何其他通配符参数作为其后续参数。在此示例中,我们使用{orderId}
占位符来指示频道名称的“ID”部分是通配符。
监听事件广播
接下来,剩下的就是在我们的 JavaScript 应用程序中监听事件。我们可以使用Laravel Echo来实现。Laravel Echo 内置的 React 和 Vue hooks 使其易于上手,并且默认情况下,事件的所有公共属性都将包含在广播事件中:
1import { useEcho } from "@laravel/echo-react";2 3useEcho(4 `orders.${orderId}`,5 "OrderShipmentStatusUpdated",6 (e) => {7 console.log(e.order);8 },9);
1<script setup lang="ts"> 2import { useEcho } from "@laravel/echo-vue"; 3 4useEcho( 5 `orders.${orderId}`, 6 "OrderShipmentStatusUpdated", 7 (e) => { 8 console.log(e.order); 9 },10);11</script>
定义广播事件
要通知 Laravel 广播指定事件,您必须Illuminate\Contracts\Broadcasting\ShouldBroadcast
在事件类上实现相应的接口。此接口已导入到框架生成的所有事件类中,因此您可以轻松地将其添加到任何事件中。
该ShouldBroadcast
接口只需实现一个方法:broadcastOn
。该broadcastOn
方法应返回一个频道或频道数组,用于广播事件。频道应为Channel
、PrivateChannel
或 的实例PresenceChannel
。 的实例Channel
表示任何用户均可订阅的公共频道,而PrivateChannels
和 的实例表示需要频道授权PresenceChannels
的私有频道:
1<?php 2 3namespace App\Events; 4 5use App\Models\User; 6use Illuminate\Broadcasting\Channel; 7use Illuminate\Broadcasting\InteractsWithSockets; 8use Illuminate\Broadcasting\PresenceChannel; 9use Illuminate\Broadcasting\PrivateChannel;10use Illuminate\Contracts\Broadcasting\ShouldBroadcast;11use Illuminate\Queue\SerializesModels;12 13class ServerCreated implements ShouldBroadcast14{15 use SerializesModels;16 17 /**18 * Create a new event instance.19 */20 public function __construct(21 public User $user,22 ) {}23 24 /**25 * Get the channels the event should broadcast on.26 *27 * @return array<int, \Illuminate\Broadcasting\Channel>28 */29 public function broadcastOn(): array30 {31 return [32 new PrivateChannel('user.'.$this->user->id),33 ];34 }35}
实现该接口后ShouldBroadcast
,您只需像平常一样触发该事件即可。触发该事件后,队列任务将自动使用您指定的广播驱动程序广播该事件。
广播名称
默认情况下,Laravel 将使用事件的类名来广播该事件。但是,您可以通过broadcastAs
在事件上定义方法来自定义广播名称:
1/**2 * The event's broadcast name.3 */4public function broadcastAs(): string5{6 return 'server.created';7}
如果你使用该方法自定义广播名称broadcastAs
,则应确保以一个前导.
字符注册监听器。这将指示 Echo 不将应用程序的命名空间添加到事件的前面:
1.listen('.server.created', function (e) {2 // ...3});
广播数据
当事件被广播时,其所有public
属性都会自动序列化并作为事件的有效负载进行广播,从而允许你在 JavaScript 应用程序中访问其任何公共数据。例如,如果你的事件有一个$user
包含 Eloquent 模型的公共属性,则该事件的广播有效负载将是:
1{2 "user": {3 "id": 1,4 "name": "Patrick Stewart"5 ...6 }7}
但是,如果您希望对广播负载进行更细粒度的控制,可以broadcastWith
向事件添加一个方法。此方法应返回您希望作为事件负载广播的数据数组:
1/**2 * Get the data to broadcast.3 *4 * @return array<string, mixed>5 */6public function broadcastWith(): array7{8 return ['id' => $this->user->id];9}
广播队列
默认情况下,每个广播事件都会被放置在配置文件中指定的默认队列连接的默认队列中。您可以通过在事件类中定义和属性queue.php
来自定义广播器使用的队列连接和名称:connection
queue
1/** 2 * The name of the queue connection to use when broadcasting the event. 3 * 4 * @var string 5 */ 6public $connection = 'redis'; 7 8/** 9 * The name of the queue on which to place the broadcasting job.10 *11 * @var string12 */13public $queue = 'default';
broadcastQueue
或者,您可以通过在事件上定义方法来自定义队列名称:
1/**2 * The name of the queue on which to place the broadcasting job.3 */4public function broadcastQueue(): string5{6 return 'default';7}
如果您希望使用sync
队列而不是默认队列驱动程序来广播事件,则可以实现ShouldBroadcastNow
接口而不是ShouldBroadcast
:
1<?php 2 3namespace App\Events; 4 5use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; 6 7class OrderShipmentStatusUpdated implements ShouldBroadcastNow 8{ 9 // ...10}
播出条件
有时,您希望仅在给定条件成立时才广播事件。您可以通过broadcastWhen
向事件类添加方法来定义这些条件:
1/**2 * Determine if this event should broadcast.3 */4public function broadcastWhen(): bool5{6 return $this->order->value > 100;7}
广播和数据库交易
当广播事件在数据库事务中被调度时,它们可能会在数据库事务提交之前就被队列处理。发生这种情况时,您在数据库事务期间对模型或数据库记录所做的任何更新可能尚未反映在数据库中。此外,在事务中创建的任何模型或数据库记录可能都不存在于数据库中。如果您的事件依赖于这些模型,则在处理广播事件的作业时可能会发生意外错误。
如果您的队列连接的after_commit
配置选项设置为,您仍然可以通过实现事件类上的接口false
来指示在提交所有打开的数据库事务后应分派特定的广播事件:ShouldDispatchAfterCommit
1<?php 2 3namespace App\Events; 4 5use Illuminate\Contracts\Broadcasting\ShouldBroadcast; 6use Illuminate\Contracts\Events\ShouldDispatchAfterCommit; 7use Illuminate\Queue\SerializesModels; 8 9class ServerCreated implements ShouldBroadcast, ShouldDispatchAfterCommit10{11 use SerializesModels;12}
授权渠道
私有频道需要您授权当前已验证的用户能够实际收听该频道。具体方法是向 Laravel 应用程序发送一个包含频道名称的 HTTP 请求,并允许应用程序判断用户是否可以收听该频道。使用Laravel Echo时,系统会自动发出授权订阅私有频道的 HTTP 请求。
启用广播后,Laravel 会自动注册/broadcasting/auth
路由来处理授权请求。该/broadcasting/auth
路由会自动放置在web
中间件组中。
定义授权回调
接下来,我们需要定义逻辑来判断当前已认证用户是否可以监听指定频道。这在Artisan 命令routes/channels.php
创建的文件中完成install:broadcasting
。在这个文件中,你可以使用以下Broadcast::channel
方法来注册频道授权回调:
1use App\Models\User;2 3Broadcast::channel('orders.{orderId}', function (User $user, int $orderId) {4 return $user->id === Order::findOrNew($orderId)->user_id;5});
该channel
方法接受两个参数:频道名称和返回true
或false
指示用户是否有权在该频道上收听的回调。
所有授权回调都会接收当前已验证的用户作为其第一个参数,并将任何其他通配符参数作为其后续参数。在此示例中,我们使用{orderId}
占位符来指示频道名称的“ID”部分是通配符。
您可以使用 Artisan 命令查看应用程序的广播授权回调列表channel:list
:
1php artisan channel:list
授权回调模型绑定
与 HTTP 路由类似,通道路由也可以利用隐式和显式路由模型绑定。例如,除了接收字符串或数字形式的订单 ID,你还可以请求一个实际的Order
模型实例:
1use App\Models\Order;2use App\Models\User;3 4Broadcast::channel('orders.{order}', function (User $user, Order $order) {5 return $user->id === $order->user_id;6});
与 HTTP 路由模型绑定不同,通道模型绑定不支持自动隐式模型绑定范围界定。不过,这很少会成为问题,因为大多数通道可以基于单个模型的唯一主键来限定范围。
授权回调认证
私有广播频道和在线状态广播频道通过应用默认的身份验证守卫对当前用户进行身份验证。如果用户未通过身份验证,频道授权将被自动拒绝,并且授权回调不会被执行。但是,您可以根据需要指定多个自定义守卫来对传入的请求进行身份验证:
1Broadcast::channel('channel', function () {2 // ...3}, ['guards' => ['web', 'admin']]);
定义通道类别
如果您的应用程序使用许多不同的通道,routes/channels.php
文件可能会变得非常庞大。因此,您可以使用通道类来授权通道,而不是使用闭包。要生成通道类,请使用make:channel
Artisan 命令。此命令会在目录中放置一个新的通道类App/Broadcasting
。
1php artisan make:channel OrderChannel
接下来,在您的文件中注册您的频道routes/channels.php
:
1use App\Broadcasting\OrderChannel;2 3Broadcast::channel('orders.{order}', OrderChannel::class);
最后,您可以将频道的授权逻辑放在频道类的join
方法中。此join
方法将包含您通常放在频道授权闭包中的逻辑。您还可以利用频道模型绑定:
1<?php 2 3namespace App\Broadcasting; 4 5use App\Models\Order; 6use App\Models\User; 7 8class OrderChannel 9{10 /**11 * Create a new channel instance.12 */13 public function __construct() {}14 15 /**16 * Authenticate the user's access to the channel.17 */18 public function join(User $user, Order $order): array|bool19 {20 return $user->id === $order->user_id;21 }22}
与 Laravel 中的许多其他类一样,通道类将由服务容器 自动解析。因此,您可以在通道的构造函数中键入所需的任何依赖项。
广播Events
定义事件并用ShouldBroadcast
接口标记后,只需使用事件的 dispatch 方法触发该事件即可。事件调度器会注意到该事件已用ShouldBroadcast
接口标记,并将该事件加入队列进行广播:
1use App\Events\OrderShipmentStatusUpdated;2 3OrderShipmentStatusUpdated::dispatch($order);
仅限他人
在构建使用事件广播的应用程序时,有时可能需要将事件广播给指定频道的所有订阅者(当前用户除外)。您可以使用broadcast
Helpers类和toOthers
方法来实现:
1use App\Events\OrderShipmentStatusUpdated;2 3broadcast(new OrderShipmentStatusUpdated($update))->toOthers();
为了更好地理解何时需要使用该toOthers
方法,我们设想一个任务列表应用,用户可以通过输入任务名称来创建新任务。要创建任务,你的应用可能会向一个/task
URL 发出请求,该 URL 广播任务创建的消息,并返回新任务的 JSON 格式。当你的 JavaScript 应用收到来自终端的响应时,它可能会直接将新任务插入到其任务列表中,如下所示:
1axios.post('/task', task)2 .then((response) => {3 this.tasks.push(response.data);4 });
但是,请记住,我们还会广播任务的创建事件。如果您的 JavaScript 应用程序也监听此事件以便将任务添加到任务列表中,则列表中会出现重复的任务:一个来自终端,一个来自广播。您可以使用该toOthers
方法指示广播器不向当前用户广播该事件来解决这个问题。
您的事件必须使用该Illuminate\Broadcasting\InteractsWithSockets
特征才能调用该toOthers
方法。
配置
初始化 Laravel Echo 实例时,会为连接分配一个套接字 ID。如果您使用全局Axios实例从 JavaScript 应用程序发出 HTTP 请求,则套接字 ID 将自动作为X-Socket-ID
标头附加到每个发出的请求中。然后,当您调用该toOthers
方法时,Laravel 将从标头中提取套接字 ID,并指示广播器不向任何具有该套接字 ID 的连接进行广播。
如果您没有使用全局 Axios 实例,则需要手动配置 JavaScript 应用程序,以便将X-Socket-ID
标头随所有发出的请求一起发送。您可以使用以下命令获取套接字 ID Echo.socketId
:
1var socketId = Echo.socketId();
自定义连接
如果您的应用程序与多个广播连接进行交互,并且您想要使用默认广播器以外的广播器来广播事件,则可以使用该via
方法指定将事件推送到哪个连接:
1use App\Events\OrderShipmentStatusUpdated;2 3broadcast(new OrderShipmentStatusUpdated($update))->via('pusher');
broadcastVia
或者,你也可以通过调用事件构造函数中的方法来指定事件的广播连接。不过,在执行此操作之前,你应该确保事件类使用了以下InteractsWithBroadcasting
特征:
1<?php 2 3namespace App\Events; 4 5use Illuminate\Broadcasting\Channel; 6use Illuminate\Broadcasting\InteractsWithBroadcasting; 7use Illuminate\Broadcasting\InteractsWithSockets; 8use Illuminate\Broadcasting\PresenceChannel; 9use Illuminate\Broadcasting\PrivateChannel;10use Illuminate\Contracts\Broadcasting\ShouldBroadcast;11use Illuminate\Queue\SerializesModels;12 13class OrderShipmentStatusUpdated implements ShouldBroadcast14{15 use InteractsWithBroadcasting;16 17 /**18 * Create a new event instance.19 */20 public function __construct()21 {22 $this->broadcastVia('pusher');23 }24}
匿名事件
有时,你可能希望将一个简单的事件广播到应用程序的前端,而无需创建专门的事件类。为了满足这种情况,Broadcast
外观层允许你广播“匿名事件”:
1Broadcast::on('orders.'.$order->id)->send();
上面的例子将广播以下事件:
1{2 "event": "AnonymousEvent",3 "data": "[]",4 "channel": "orders.1"5}
使用as
和with
方法,您可以自定义事件的名称和数据:
1Broadcast::on('orders.'.$order->id)2 ->as('OrderPlaced')3 ->with($order)4 ->send();
上面的例子将广播如下事件:
1{2 "event": "OrderPlaced",3 "data": "{ id: 1, total: 100 }",4 "channel": "orders.1"5}
如果您想在私人或在线频道上广播匿名事件,您可以使用private
和presence
方法:
1Broadcast::private('orders.'.$order->id)->send();2Broadcast::presence('channels.'.$channel->id)->send();
使用 方法来广播匿名事件,send
会将该事件调度到应用程序的队列中进行处理。但是,如果您想立即广播该事件,可以使用sendNow
方法来广播:
1Broadcast::on('orders.'.$order->id)->sendNow();
要将事件广播给除当前已验证用户之外的所有频道订阅者,您可以调用该toOthers
方法:
1Broadcast::on('orders.'.$order->id)2 ->toOthers()3 ->send();
接收广播
监听事件
安装并实例化 Laravel Echo后,即可开始监听 Laravel 应用程序广播的事件。首先,使用channel
方法来获取频道实例,然后调用listen
方法来监听指定的事件:
1Echo.channel(`orders.${this.order.id}`)2 .listen('OrderShipmentStatusUpdated', (e) => {3 console.log(e.order.name);4 });
如果您想在私有频道上监听事件,请使用该private
方法。您可以继续链接调用该listen
方法,以在单个频道上监听多个事件:
1Echo.private(`orders.${this.order.id}`)2 .listen(/* ... */)3 .listen(/* ... */)4 .listen(/* ... */);
停止监听事件
如果您想在不离开频道的情况下停止监听给定事件,您可以使用该stopListening
方法:
1Echo.private(`orders.${this.order.id}`)2 .stopListening('OrderShipmentStatusUpdated');
离开频道
要离开频道,您可以调用leaveChannel
Echo 实例上的方法:
1Echo.leaveChannel(`orders.${this.order.id}`);
如果您想离开某个频道及其关联的私人频道和在线频道,您可以调用该leave
方法:
1Echo.leave(`orders.${this.order.id}`);
命名空间
你可能已经注意到,在上面的示例中,我们没有App\Events
为事件类指定完整的命名空间。这是因为 Echo 会自动假定事件位于该App\Events
命名空间中。但是,你可以在实例化 Echo 时通过传递配置选项来配置根命名空间namespace
:
1window.Echo = new Echo({2 broadcaster: 'pusher',3 // ...4 namespace: 'App.Other.Namespace'5});
或者,你可以在使用 Echo 订阅事件类时为其添加前缀.
。这样你就可以始终指定完全限定的类名:
1Echo.channel('orders')2 .listen('.Namespace\\Event\\Class', (e) => {3 // ...4 });
使用 React 或 Vue
Laravel Echo 包含 React 和 Vue 钩子,可轻松监听事件。首先,调用useEcho
用于监听私有事件的钩子。useEcho
当使用组件卸载时,钩子将自动退出通道:
1import { useEcho } from "@laravel/echo-react";2 3useEcho(4 `orders.${orderId}`,5 "OrderShipmentStatusUpdated",6 (e) => {7 console.log(e.order);8 },9);
1<script setup lang="ts"> 2import { useEcho } from "@laravel/echo-vue"; 3 4useEcho( 5 `orders.${orderId}`, 6 "OrderShipmentStatusUpdated", 7 (e) => { 8 console.log(e.order); 9 },10);11</script>
您可以通过提供一系列事件来监听多个事件useEcho
:
1useEcho(2 `orders.${orderId}`,3 ["OrderShipmentStatusUpdated", "OrderShipped"],4 (e) => {5 console.log(e.order);6 },7);
您还可以指定广播事件有效负载数据的形状,以提供更高的类型安全性和编辑便利性:
1type OrderData = { 2 order: { 3 id: number; 4 user: { 5 id: number; 6 name: string; 7 }; 8 created_at: string; 9 };10};11 12useEcho<OrderData>(`orders.${orderId}`, "OrderShipmentStatusUpdated", (e) => {13 console.log(e.order.id);14 console.log(e.order.user.id);15});
useEcho
当使用组件卸载时,钩子将自动离开通道;但是,您可以利用返回的函数在必要时以编程方式手动停止/开始监听通道:
1import { useEcho } from "@laravel/echo-react"; 2 3const { leaveChannel, leave, stopListening, listen } = useEcho( 4 `orders.${orderId}`, 5 "OrderShipmentStatusUpdated", 6 (e) => { 7 console.log(e.order); 8 }, 9);10 11// Stop listening without leaving channel...12stopListening();13 14// Start listening again...15listen();16 17// Leave channel...18leaveChannel();19 20// Leave a channel and also its associated private and presence channels...21leave();
1<script setup lang="ts"> 2import { useEcho } from "@laravel/echo-vue"; 3 4const { leaveChannel, leave, stopListening, listen } = useEcho( 5 `orders.${orderId}`, 6 "OrderShipmentStatusUpdated", 7 (e) => { 8 console.log(e.order); 9 },10);11 12// Stop listening without leaving channel...13stopListening();14 15// Start listening again...16listen();17 18// Leave channel...19leaveChannel();20 21// Leave a channel and also its associated private and presence channels...22leave();23</script>
连接到公共频道
要连接到公共频道,您可以使用useEchoPublic
钩子:
1import { useEchoPublic } from "@laravel/echo-react";2 3useEchoPublic("posts", "PostPublished", (e) => {4 console.log(e.post);5});
1<script setup lang="ts">2import { useEchoPublic } from "@laravel/echo-vue";3 4useEchoPublic("posts", "PostPublished", (e) => {5 console.log(e.post);6});7</script>
连接到 Presence Channels
要连接到存在通道,您可以使用useEchoPresence
钩子:
1import { useEchoPresence } from "@laravel/echo-react";2 3useEchoPresence("posts", "PostPublished", (e) => {4 console.log(e.post);5});
1<script setup lang="ts">2import { useEchoPresence } from "@laravel/echo-vue";3 4useEchoPresence("posts", "PostPublished", (e) => {5 console.log(e.post);6});7</script>
存在通道
在线状态频道在私人频道的安全性基础上,还新增了频道订阅者信息感知功能。这使得构建强大的协作应用功能变得轻而易举,例如当其他用户正在查看同一页面时通知用户,或列出聊天室成员信息。
授权在线状态通道
所有在线状态频道也都是私有频道;因此,用户必须获得授权才能访问它们。但是,在为在线状态频道定义授权回调时,您不会返回true
用户是否有权加入频道。相反,您应该返回一个包含用户数据的数组。
授权回调返回的数据将提供给 JavaScript 应用中的在线状态频道事件监听器。如果用户未被授权加入在线状态频道,则应返回false
或null
:
1use App\Models\User;2 3Broadcast::channel('chat.{roomId}', function (User $user, int $roomId) {4 if ($user->canJoinRoom($roomId)) {5 return ['id' => $user->id, 'name' => $user->name];6 }7});
加入在线状态频道
要加入在线状态频道,您可以使用 Echo 的join
方法。该join
方法将返回一个PresenceChannel
实现,除了公开listen
方法之外,它还允许您订阅here
、joining
和leaving
事件。
1Echo.join(`chat.${roomId}`) 2 .here((users) => { 3 // ... 4 }) 5 .joining((user) => { 6 console.log(user.name); 7 }) 8 .leaving((user) => { 9 console.log(user.name);10 })11 .error((error) => {12 console.error(error);13 });
here
成功加入频道后,回调函数会立即执行,并接收一个数组,其中包含当前订阅该频道的所有其他用户的用户信息。新用户加入频道时会执行该方法joining
,leaving
用户离开频道时会执行该方法。error
当身份验证端点返回除 200 以外的 HTTP 状态码,或者解析返回的 JSON 时出现问题时,也会执行该方法。
向 Presence Channels 进行广播
在线状态频道可以像公共频道或私人频道一样接收事件。以聊天室为例,我们可能希望将NewMessage
事件广播到聊天室的在线状态频道。为此,我们将从PresenceChannel
事件的broadcastOn
方法中返回一个实例:
1/** 2 * Get the channels the event should broadcast on. 3 * 4 * @return array<int, \Illuminate\Broadcasting\Channel> 5 */ 6public function broadcastOn(): array 7{ 8 return [ 9 new PresenceChannel('chat.'.$this->message->room_id),10 ];11}
与其他事件一样,您可以使用broadcast
帮助程序和toOthers
方法来排除当前用户接收广播:
1broadcast(new NewMessage($message));2 3broadcast(new NewMessage($message))->toOthers();
与其他类型的事件一样,您可以使用 Echo 的listen
方法监听发送到在线状态通道的事件:
1Echo.join(`chat.${roomId}`)2 .here(/* ... */)3 .joining(/* ... */)4 .leaving(/* ... */)5 .listen('NewMessage', (e) => {6 // ...7 });
模特广播
在阅读以下有关模型广播的文档之前,我们建议您熟悉 Laravel 模型广播服务的一般概念以及如何手动创建和监听广播事件。
在应用程序的Eloquent 模型创建、更新或删除时,广播事件是很常见的。当然,这可以通过手动定义 Eloquent 模型状态变化的自定义事件并使用接口标记这些事件来轻松实现ShouldBroadcast
。
但是,如果您在应用程序中没有将这些事件用于其他目的,那么仅出于广播目的创建事件类可能会很麻烦。为了解决这个问题,Laravel 允许您指示 Eloquent 模型应自动广播其状态变化。
首先,你的 Eloquent 模型应该使用Illuminate\Database\Eloquent\BroadcastsEvents
trait。此外,模型应该定义一个broadcastOn
方法,该方法将返回一个通道数组,模型的事件应该在这些通道上广播:
1<?php 2 3namespace App\Models; 4 5use Illuminate\Broadcasting\Channel; 6use Illuminate\Broadcasting\PrivateChannel; 7use Illuminate\Database\Eloquent\BroadcastsEvents; 8use Illuminate\Database\Eloquent\Factories\HasFactory; 9use Illuminate\Database\Eloquent\Model;10use Illuminate\Database\Eloquent\Relations\BelongsTo;11 12class Post extends Model13{14 use BroadcastsEvents, HasFactory;15 16 /**17 * Get the user that the post belongs to.18 */19 public function user(): BelongsTo20 {21 return $this->belongsTo(User::class);22 }23 24 /**25 * Get the channels that model events should broadcast on.26 *27 * @return array<int, \Illuminate\Broadcasting\Channel|\Illuminate\Database\Eloquent\Model>28 */29 public function broadcastOn(string $event): array30 {31 return [$this, $this->user];32 }33}
一旦您的模型包含此特征并定义其广播渠道,它将在创建、更新、删除、丢弃或恢复模型实例时开始自动广播事件。
此外,您可能注意到该broadcastOn
方法接收一个字符串$event
参数。此参数包含模型上发生的事件类型,其值为created
、updated
、deleted
、trashed
或restored
。通过检查此变量的值,您可以确定模型应该针对特定事件向哪些渠道(如果有)进行广播:
1/** 2 * Get the channels that model events should broadcast on. 3 * 4 * @return array<string, array<int, \Illuminate\Broadcasting\Channel|\Illuminate\Database\Eloquent\Model>> 5 */ 6public function broadcastOn(string $event): array 7{ 8 return match ($event) { 9 'deleted' => [],10 default => [$this, $this->user],11 };12}
自定义模型广播事件创建
有时,你可能希望自定义 Laravel 创建底层模型广播事件的方式。你可以newBroadcastableEvent
在 Eloquent 模型上定义一个方法来实现。该方法应该返回一个Illuminate\Database\Eloquent\BroadcastableModelEventOccurred
实例:
1use Illuminate\Database\Eloquent\BroadcastableModelEventOccurred; 2 3/** 4 * Create a new broadcastable model event for the model. 5 */ 6protected function newBroadcastableEvent(string $event): BroadcastableModelEventOccurred 7{ 8 return (new BroadcastableModelEventOccurred( 9 $this, $event10 ))->dontBroadcastToCurrentUser();11}
模范广播大会
渠道惯例
您可能已经注意到,broadcastOn
上面模型示例中的方法没有返回Channel
实例。相反,Eloquent 模型是直接返回的。如果您的模型方法返回了 Eloquent 模型实例broadcastOn
(或包含在方法返回的数组中),Laravel 将自动使用模型的类名和主键标识符作为通道名称,为该模型实例化一个私有通道实例。
因此,App\Models\User
带有id
of的模型1
将被转换为Illuminate\Broadcasting\PrivateChannel
名称为 的实例App.Models.User.1
。当然,除了从模型broadcastOn
方法返回 Eloquent 模型实例之外,您还可以返回完整的Channel
实例,以便完全控制模型的通道名称:
1use Illuminate\Broadcasting\PrivateChannel; 2 3/** 4 * Get the channels that model events should broadcast on. 5 * 6 * @return array<int, \Illuminate\Broadcasting\Channel> 7 */ 8public function broadcastOn(string $event): array 9{10 return [11 new PrivateChannel('user.'.$this->id)12 ];13}
如果你计划在模型broadcastOn
方法中显式返回一个通道实例,可以将一个 Eloquent 模型实例传递给通道的构造函数。这样做时,Laravel 会使用上面讨论过的模型通道约定将 Eloquent 模型转换为通道名称字符串:
1return [new Channel($this->user)];
如果需要确定模型的通道名称,可以broadcastChannel
在任何模型实例上调用该方法。例如,此方法返回带有 的模型的App.Models.User.1
字符串:App\Models\User
id
1
1$user->broadcastChannel();
Events公约
由于模型广播事件与应用程序目录中的“实际”事件无关App\Events
,因此会根据约定为其分配名称和有效负载。Laravel 的约定是使用模型的类名(不包含命名空间)和触发广播的模型事件名称来广播事件。
因此,例如,模型的更新App\Models\Post
将向您的客户端应用程序广播一个事件,PostUpdated
如下所示:
1{2 "model": {3 "id": 1,4 "title": "My first post"5 ...6 },7 ...8 "socket": "someSocketId"9}
模型的删除App\Models\User
将广播一个名为的事件UserDeleted
。
如果您愿意,可以通过在模型中添加broadcastAs
and方法来定义自定义广播名称和负载。这些方法接收正在发生的模型事件/操作的名称,允许您为每个模型操作自定义事件的名称和负载。如果从方法返回,Laravel 将在广播事件时使用上面讨论过的模型广播事件名称约定:broadcastWith
null
broadcastAs
1/** 2 * The model event's broadcast name. 3 */ 4public function broadcastAs(string $event): string|null 5{ 6 return match ($event) { 7 'created' => 'post.created', 8 default => null, 9 };10}11 12/**13 * Get the data to broadcast for the model.14 *15 * @return array<string, mixed>16 */17public function broadcastWith(string $event): array18{19 return match ($event) {20 'created' => ['title' => $this->title],21 default => ['model' => $this],22 };23}
监听模型广播
将特征添加BroadcastsEvents
到模型并定义模型broadcastOn
方法后,您就可以在客户端应用程序中监听广播的模型事件了。在开始之前,您可以参考关于监听事件的完整文档。
首先,使用该private
方法获取一个通道实例,然后调用该listen
方法监听指定的事件。通常,传递给该private
方法的通道名称应符合 Laravel模型广播约定。
获取频道实例后,您可以使用该listen
方法监听特定事件。由于模型广播事件与应用程序App\Events
目录中的“实际”事件无关,因此事件名称必须以 为前缀,.
以表明它不属于特定的命名空间。每个模型广播事件都有一个model
属性,该属性包含该模型的所有可广播属性:
1Echo.private(`App.Models.User.${this.user.id}`)2 .listen('.UserUpdated', (e) => {3 console.log(e.model);4 });
使用 React 或 Vue
如果您正在使用 React 或 Vue,您可以使用 Laravel Echo 附带的useEchoModel
钩子轻松监听模型广播:
1import { useEchoModel } from "@laravel/echo-react";2 3useEchoModel("App.Models.User", userId, ["UserUpdated"], (e) => {4 console.log(e.model);5});
1<script setup lang="ts">2import { useEchoModel } from "@laravel/echo-vue";3 4useEchoModel("App.Models.User", userId, ["UserUpdated"], (e) => {5 console.log(e.model);6});7</script>
您还可以指定模型事件有效负载数据的形状,从而提供更高的类型安全性和编辑便利性:
1type User = { 2 id: number; 3 name: string; 4 email: string; 5}; 6 7useEchoModel<User, "App.Models.User">("App.Models.User", userId, ["UserUpdated"], (e) => { 8 console.log(e.model.id); 9 console.log(e.model.name);10});
客户Events
使用推送通道时,您必须在应用程序仪表板的“应用程序设置”部分中启用“客户端事件”选项才能发送客户端事件。
有时你可能希望将事件广播给其他已连接的客户端,而无需访问你的 Laravel 应用程序。这对于诸如“输入”通知之类的情况尤其有用,你需要提醒应用程序的用户,有其他用户正在给定屏幕上输入消息。
要广播客户端事件,您可以使用 Echo 的whisper
方法:
1Echo.private(`chat.${roomId}`)2 .whisper('typing', {3 name: this.user.name4 });
1import { useEcho } from "@laravel/echo-react";2 3const { channel } = useEcho(`chat.${roomId}`, ['update'], (e) => {4 console.log('Chat event received:', e);5});6 7channel().whisper('typing', { name: user.name });
1<script setup lang="ts">2import { useEcho } from "@laravel/echo-vue";3 4const { channel } = useEcho(`chat.${roomId}`, ['update'], (e) => {5 console.log('Chat event received:', e);6});7 8channel().whisper('typing', { name: user.name });9</script>
要监听客户端事件,您可以使用该listenForWhisper
方法:
1Echo.private(`chat.${roomId}`)2 .listenForWhisper('typing', (e) => {3 console.log(e.name);4 });
1import { useEcho } from "@laravel/echo-react";2 3const { channel } = useEcho(`chat.${roomId}`, ['update'], (e) => {4 console.log('Chat event received:', e);5});6 7channel().listenForWhisper('typing', (e) => {8 console.log(e.name);9});
1<script setup lang="ts"> 2import { useEcho } from "@laravel/echo-vue"; 3 4const { channel } = useEcho(`chat.${roomId}`, ['update'], (e) => { 5 console.log('Chat event received:', e); 6}); 7 8channel().listenForWhisper('typing', (e) => { 9 console.log(e.name);10});11</script>
通知
通过将事件广播与通知配对,您的 JavaScript 应用程序无需刷新页面即可接收新通知。在开始之前,请务必阅读有关使用广播通知渠道的文档。
配置通知使用广播通道后,您可以使用 Echo 的notification
方法监听广播事件。请记住,通道名称应与接收通知的实体的类名匹配:
1Echo.private(`App.Models.User.${userId}`)2 .notification((notification) => {3 console.log(notification.type);4 });
1import { useEchoModel } from "@laravel/echo-react";2 3const { channel } = useEchoModel('App.Models.User', userId);4 5channel().notification((notification) => {6 console.log(notification.type);7});
1<script setup lang="ts">2import { useEchoModel } from "@laravel/echo-vue";3 4const { channel } = useEchoModel('App.Models.User', userId);5 6channel().notification((notification) => {7 console.log(notification.type);8});9</script>
App\Models\User
在此示例中,所有通过该渠道发送到实例的通知broadcast
都将由回调接收。该App.Models.User.{id}
渠道的渠道授权回调包含在您的应用程序routes/channels.php
文件中。