Système de diffusion
- Fournisseur de services de diffusion
- Jeton CSRF
- Exigences du pilote
- Socket.IO Interface ShouldBroadcast
- Canal autorisé
- File d'attente de diffusion
- Conditions de diffusion
- Canal d'autorisation
- Définir l'itinéraire d'autorisation
- Point de terminaison d'autorisation personnalisé
- Définir le rappel d'autorisation
- Utilisez une instance client existante Espace de noms
- Système de diffusion
- Définir les événements de diffusionFile d'attente de diffusion
- Conditions de diffusionCanal d'autorisation
- Définir l'itinéraire d'autorisationDiffuser uniquement à d'autres
- Quitter le canal
- espace de noms
- Introduction
- Dans les applications Web modernes, les WebSockets sont utilisés pour implémenter des interfaces utilisateur en temps réel et mises à jour instantanément. Lorsque les données sur le serveur sont mises à jour, les informations de mise à jour sont envoyées au client via la connexion WebSocket pour traitement. Il s'agit d'une option plus fiable et plus efficace que d'interroger constamment l'application. Pour vous aider à construire ce type d'application, Laravel facilitera la « diffusion » d'événements via des connexions WebSocket. La diffusion d'événements Laravel vous permet de partager le même nom d'événement entre les applications JavaScript côté serveur et côté client.
- {Note} Avant d'en savoir plus sur la diffusion d'événements, assurez-vous d'avoir lu toute la documentation sur les événements et les auditeurs Laravel.
Configuration
Toutes les configurations concernant la diffusion d'événements sont enregistrées dans le fichier de configuration
config/broadcasting.php
. Laravel est livré avec plusieurs pilotes de diffusion : Pusher, Redis et un pilotelog
pour le développement local et le débogage. De plus, il existe un pilotenull
qui vous permet de désactiver complètement le système de diffusion. Des exemples de configurations pour chaque pilote peuvent être trouvés dans le fichier de configurationconfig/broadcasting.php
.config/broadcasting.php
配置文件中。 Laravel 自带了几个广播驱动: Pusher 、 Redis , 和一个用于本地开发与调试的log
驱动。另外,还有一个null
驱动允许你完全关闭广播系统。每一个驱动的示例配置都可以在config/broadcasting.php
配置文件中找到。广播服务提供者
在对事件进行广播之前,你必须先注册
AppProvidersBroadcastServiceProvider
。对于一个新建的 Laravel 应用程序,你只需要在config/app.php
配置文件的providers
数组中取消对该提供者的注释即可。该提供者将允许你注册广播授权路由和回调。CSRF 令牌
Laravel Echo 需要访问当前会话的 CSRF 令牌。你应当验证你的应用程序的
head
HTML 元素是否定义了包含 CSRF 令牌的meta
标签:<meta name="csrf-token" content="{{ csrf_token() }}">
对驱动的要求
Pusher
如果你使用 Pusher 来对事件进行广播,请用 Composer 包管理器来安装 Pusher PHP SDK :
composer require pusher/pusher-php-server "~3.0"
然后,你需要在
config/broadcasting.php
配置文件中配置你的 Pusher 证书。该文件中已经包含了一个 Pusher 示例配置,你可以快速地指定你的 Pusher key 、secret 和 application ID。config/broadcasting.php
文件的pusher
配置项同时也允许你指定 Pusher 支持的额外options
,例如 cluster:'options' => [ 'cluster' => 'eu', 'encrypted' => true ],
当 Pusher 和 Laravel Echo 一起使用时,你应该在
resources/assets/js/bootstrap.js
文件中实例化 Echo 对象时指定pusher
作为所需要的 broadcaster :import Echo from "laravel-echo"window.Pusher = require('pusher-js'); window.Echo = new Echo({ broadcaster: 'pusher', key: 'your-pusher-key' });
Redis
如果你使用 Redis 广播器,请安装 Predis 库:
composer require predis/predis
Redis 广播器会使用 Redis 的 发布 / 订阅 特性来广播消息;尽管如此,你仍需将它与能够从 Redis 接收消息的 WebSocket 服务器配对使用以便将消息广播到你的 WebSocket 频道上去。
当 Redis 广播器发布一个事件的时候,该事件会被发布到它指定的频道上去,传输的数据是一个采用 JSON 编码的字符串。该字符串包含了事件名、
data
Fournisseur de services de diffusion
Avant de diffuser un événement, vous devez d'abord enregistrerAppProvidersBroadcastServiceProvider
. Pour une nouvelle application Laravel, il vous suffit de décommenter le fournisseur dans le tableauproviders
du fichier de configurationconfig/app.php
. Ce fournisseur vous permettra d'enregistrer les itinéraires d'autorisation de diffusion et les rappels.🎜Jeton CSRF
🎜Laravel Echo nécessite un accès au current Le jeton CSRF de la session. Vous devez vérifier que l'élément HTMLhead
de votre application définit la balisemeta
qui contient le jeton CSRF : 🎜npm install --save socket.io-client
🎜< /a> 🎜🎜🎜Exigences pour les conducteurs🎜🎜Pusher
🎜Si vous utilisez Pusher pour diffuser des événements, veuillez utiliser le gestionnaire de packages Composer pour installer le SDK PHP Pusher : 🎜import Echo from "laravel-echo"window.io = require('socket.io-client'); window.Echo = new Echo({ broadcaster: 'socket.io', host: window.location.hostname + ':6001' });
🎜Ensuite, vous devez < Configurer votre certificat Pusher dans le code>config/broadcasting.php fichier de configuration. Ce fichier contient déjà un exemple de configuration Pusher afin que vous puissiez spécifier rapidement votre clé Pusher, votre secret et votre ID d'application. L'élément de configurationpusher
dans le fichierconfig/broadcasting.php
vous permet également de spécifier desoptions
supplémentaires prises en charge par Pusher, telles que cluster : 🎜event(new ShippingStatusUpdated($update));
🎜Lorsque Pusher Lorsqu'il est utilisé avec Laravel Echo, vous devez instancier l'objet Echo dans leresources/assets/js/bootstrap.js
file Spécifiezpusher
comme diffuseur requis : 🎜<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class ShippingStatusUpdated implements ShouldBroadcast{ /** * 有关配送状态更新的信息。 * * @var string */ public $update; }
🎜Redis
🎜Si vous utilisez le diffuseur Redis, veuillez Installez la bibliothèque Predis : 🎜/** * 获取事件应该广播的频道。 * * @return array */ public function broadcastOn(){ return new PrivateChannel('order.'.$this->update->order_id); }
🎜Le diffuseur Redis utilise la fonctionnalité de publication/abonnement de Redis pour diffuser des messages ; cependant, vous devez toujours le coupler avec un serveur WebSocket capable de recevoir des messages de Redis afin de diffuser des messages sur votre chaîne WebSocket. Monter. 🎜🎜Lorsque le diffuseur Redis publie un événement, l'événement sera publié sur son canal désigné et les données transmises sont une chaîne codée en JSON. Cette chaîne contient le nom de l'événement, les donnéesdata
et l'utilisateur qui a généré l'ID de socket d'événement (si disponible). 🎜🎜🎜Socket.IO
Si vous souhaitez associer un diffuseur Redis à un serveur Socket.IO, vous devez introduire la bibliothèque client JavaScript Socket.IO dans votre application. Vous pouvez l'installer via le gestionnaire de packages NPM :
Broadcast::channel('order.{orderId}', function ($user, $orderId) { return $user->id === Order::findOrNew($orderId)->user_id; });
Ensuite, vous devez spécifier le connecteur
socket.io
et l'host
lors de l'instanciation d'Echo.socket.io
连接器和host
。Echo.private(`order.${orderId}`) .listen('ShippingStatusUpdated', (e) => { console.log(e.update); });
最后,你需要运行一个与 Laravel 兼容的 Socket.IO 服务器。 Laravel 官方并没有内置 Socket.IO 服务器实现;不过,可以选择一个由社区驱动维护的项目 tlaverdure/laravel-echo-server ,目前托管在 GitHub 。
对队列的要求
在开始广播事件之前,你还需要配置和运行 队列监听器 。所有的事件广播都是通过队列任务来完成的,因此应用程序的响应时间不会受到明显影响。
概念综述
Laravel 的事件广播允许你使用基于驱动的 WebSockets 将服务端的 Laravel 事件广播到客户端的 JavaScript 应用程序。当前的 Laravel 自带了 Pusher 和 Redis 驱动。通过使用 Laravel Echo 的 Javascript 包,我们可以很方便地在客户端消费事件。
事件通过「频道」来广播,这些频道可以被指定为公开或私有的。任何访客都可以不经授权或认证订阅一个公开频道;然而,如果想要订阅一个私有频道,那么该用户必须通过认证,并获得该频道的授权。
使用示例程序
在深入了解事件广播的每个组件之前,让我们先用一个电子商务网站作为例子来概览一下。我们不会讨论配置 Pusher 或者 Laravel Echo 的细节,这些会在本文档的其它章节里详细讨论。
在我们的应用程序中,我们假设有一个允许用户查看订单配送状态的页面。有一个
ShippingStatusUpdated
<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class ServerCreated implements ShouldBroadcast{ use SerializesModels; public $user; /** * 创建一个新的事件实例。 * * @return void */ public function __construct(User $user) { $this->user = $user; } /** *获得事件广播的频道。 * * @return Channel|array */ public function broadcastOn() { return new PrivateChannel('user.'.$this->user->id); } }
Enfin, vous devez exécuter un serveur Socket.IO compatible Laravel. Laravel n'a pas officiellement d'implémentation de serveur Socket.IO intégrée ; cependant, vous pouvez choisir un projet piloté et géré par la communauté tlaverdure. /laravel-echo-server, actuellement hébergé sur GitHub.🎜Exigences relatives aux files d'attente🎜🎜Avant de commencer à diffuser des événements, vous devez également configurer et exécuter un écouteur de file d'attente. Toute diffusion d'événements s'effectue via des tâches de file d'attente, le temps de réponse des applications ne sera donc pas affecté de manière significative. 🎜🎜🎜🎜Aperçu du concept
🎜La diffusion d'événements de Laravel vous permet d'utiliser Les WebSockets basés sur les pilotes diffusent les événements Laravel côté serveur vers les applications JavaScript côté client. Le Laravel actuel est livré avec les pilotes Pusher et Redis. En utilisant le package Javascript de Laravel Echo, nous pouvons facilement consommer des événements côté client. 🎜🎜Les événements sont diffusés via des « chaînes », qui peuvent être désignées comme publiques ou privées. Tout visiteur peut s'abonner à une chaîne publique sans autorisation ni authentification ; cependant, s'il souhaite s'abonner à une chaîne privée, l'utilisateur doit être authentifié et autorisé pour la chaîne. 🎜🎜🎜🎜Utilisation d'un exemple d'application
🎜En savoir plus sur les événements Avant d’aborder chaque composante de la diffusion, donnons un aperçu en prenant comme exemple un site e-commerce. Nous ne discuterons pas des détails de la configuration de Pusher ou de Laravel Echo, ceux-ci sera discuté dans Ceci est discuté en détail ailleurs dans ce document. 🎜🎜Dans notre application, nous supposons qu'il existe une page qui permet aux utilisateurs de visualiser l'état de livraison de la commande. Il existe un événementShippingStatusUpdated
qui sera déclenché lorsque le statut d'expédition sera mis à jour : 🎜/** * 事件的广播名称。 * * @return string */ public function broadcastAs(){ return 'server.created'; }
🎜🎜Interface
ShouldBroadcast
ShouldBroadcast
接口当用户在查看自己的订单时,我们不希望他们必须通过刷新页面才能看到状态更新。我们希望一旦有更新时就主动将更新信息广播到客户端。所以,我们必须标记
ShippingStatusUpdated
事件实现ShouldBroadcast
接口。这会让 Laravel 在事件被触发时广播该事件:.listen('.server.created', function (e) { .... });
ShouldBroadcast
接口要求事件定义一个broadcastOn
方法。该方法负责指定事件被广播到哪些频道。在(通过 Artisan 命令)生成的事件类中,一个空的broadcastOn
方法已经被预定义好了,所以我们只需要完成其细节即可。我们希望只有订单的创建者能够看到状态的更新,所以我们要把该事件广播到与这个订单绑定的私有频道上去:{ "user": { "id": 1, "name": "Patrick Stewart" ... } }
授权频道
记住,用户只有在被授权之后才能监听私有频道。我们可以在
routes/channels.php
文件中定义频道的授权规则。在本例中,我们需要对视图监听私有order.1
频道的所有用户进行验证,确保只有订单真正的创建者才能监听:/** * 指定广播数据。 * * @return array */ public function broadcastWith(){ return ['id' => $this->user->id]; }
channel
方法接收两个参数:频道名称和一个回调函数,该回调通过返回true
或者false
来表示用户是否被授权监听该频道。所有的授权回调接收当前被认证的用户作为第一个参数,任何额外的通配符参数作为后续参数。在本例中,我们使用
{orderId}
占位符来表示频道名称的 「ID」 部分是通配符。对事件广播进行监听
接下来,就只剩下在 JavaScript 应用程序中监听事件了。我们可以通过 Laravel Echo 来实现。首先,我们使用
private
方法来订阅私有频道。然后,使用listen
方法来监听ShippingStatusUpdated
Lorsque les utilisateurs consultent leurs commandes, nous ne voulons pas qu'ils aient à actualiser la page pour voir les mises à jour de statut. Nous espérons diffuser de manière proactive des informations de mise à jour aux clients une fois la mise à jour disponible. Nous devons donc marquer l'événementShippingStatusUpdated
pour implémenter l'interfaceShouldBroadcast
. Cela amènera Laravel à diffuser l'événement lorsqu'il est déclenché :/** * 事件被推送到的队列名称。 * * @var string */ public $broadcastQueue = 'your-queue-name';
L'interface
ShouldBroadcast
nécessite que l'événement définisse une méthodebroadcastOn
. Cette méthode se charge de spécifier sur quels canaux l'événement est diffusé. Dans la classe d'événement générée (via la commande Artisan), une méthodebroadcastOn
vide est déjà prédéfinie, il suffit donc de compléter ses détails. Nous espérons que seul le créateur de la commande pourra voir la mise à jour du statut, nous devons donc diffuser l'événement sur la chaîne privée liée à cette commande :<?php use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; class ShippingStatusUpdated implements ShouldBroadcastNow{ // }
Chaînes autoriséesN'oubliez pas que les utilisateurs ne peuvent surveiller les chaînes privées que s'ils sont autorisés. Nous pouvons définir des règles d'autorisation de canal dans le fichierroutes/channels.php
. Dans ce cas, nous devons authentifier tous les utilisateurs dont la vue écoute la chaîne privéeorder.1
pour garantir que seul le véritable créateur de la commande peut écouter :/** * 判定事件是否可以广播。 * * @return bool */ public function broadcastWhen(){ return $this->value > 100; }
🎜channel
méthode Reçoit deux paramètres : le nom de la chaîne et une fonction de rappel, qui indique si l'utilisateur est autorisé à écouter la chaîne en renvoyanttrue
oufalse
. 🎜🎜Tous les rappels d'autorisation reçoivent l'utilisateur actuellement authentifié comme premier paramètre, et tous les paramètres génériques supplémentaires comme paramètres suivants. Dans cet exemple, nous utilisons l'espace réservé{orderId}
pour indiquer que la partie « ID » du nom de la chaîne est un caractère générique. 🎜🎜🎜Écoute des diffusions d'événements🎜Il ne reste plus qu'à écouter les événements dans l'application JavaScript. Nous pouvons le faire avec Laravel Echo. Tout d'abord, nous utilisons la méthodeprivate
pour nous abonner à une chaîne privée. Ensuite, utilisez la méthodelisten
pour écouter l'événementShippingStatusUpdated
. Par défaut, toutes les propriétés publiques de l'événement seront incluses dans l'événement diffusé : 🎜Broadcast::routes();
🎜🎜🎜🎜🎜🎜Définir des événements de diffusion
Pour indiquer à Laravel qu'un événement donné doit être diffusé, implémentez simplement l'interface
IlluminateContractsBroadcastingShouldBroadcast
dans la classe d'événement. Cette interface a été importée dans toutes les classes d'événements générées par le framework, vous pouvez donc facilement l'ajouter à vos propres événements.IlluminateContractsBroadcastingShouldBroadcast
接口即可。该接口已被导入到所有由框架生成的事件类中,所以你可以很方便地将它添加到你自己的事件中。ShouldBroadcast
接口要求你实现一个方法:broadcastOn
。 该方法返回一个频道或者一个频道数组,事件会被广播到这些频道。这些频道必须是Channel
、PrivateChannel
或者PresenceChannel
的实例。Channel
代表任何用户都可以订阅的公开频道, 而PrivateChannels
和PresenceChannels
则代表需要 频道授权 的私有频道:Broadcast::routes($attributes);
然后,你只需要像你平时那样 触发事件 。一旦事件被触发,一个 队列任务 会自动广播事件到你指定的广播驱动上。
广播名称
Laravel 默认会使用事件的类名作为广播名称来广播事件。不过,你也可以在事件类中定义一个
broadcastAs
方法来自定义广播名称:window.Echo = new Echo({ broadcaster: 'pusher', key: 'your-pusher-key', authEndpoint: '/custom/endpoint/auth' });
如果你使用了
broadcastAs
方法来自定义广播名称,你应当确保在你注册监听器时加上一个.
的前缀。这将指示 Echo 不要在事件之前添加应用程序的命名空间:Broadcast::channel('order.{orderId}', function ($user, $orderId) { return $user->id === Order::findOrNew($orderId)->user_id; });
广播数据
当一个事件被广播时,其所有的
public
属性都会自动序列化并作为事件有效载荷进行广播,这允许你在 JavaScript 应用程序中访问到事件所有的公有数据。举个例子,如果你的事件有一个单独的包含了一个 Eloquent 模型的公有$user
属性,那么事件的广播有效载荷将会是:use App\Order; Broadcast::channel('order.{order}', function ($user, Order $order) { return $user->id === $order->user_id; });
不过,如果你想更细粒度地控制你的广播有效载荷,你可以向你的事件中添加一个
L'interfacebroadcastWith
ShouldBroadcast
vous demande d'implémenter une méthode :broadcastOn
. Cette méthode renvoie une chaîne ou un tableau de chaînes sur lesquelles l'événement sera diffusé. Ces canaux doivent être des instances deChannel
,PrivateChannel
ouPresenceChannel
.Channel
représente une chaîne publique à laquelle tout utilisateur peut s'abonner, tandis quePrivateChannels
etPresenceChannels
représentent des chaînes qui nécessitent Autorisation de chaîneChaîne privée :
Broadcast::channel('channel', function() { // ... }, ['guards' => ['web', 'admin']])
Ensuite, il vous suffit de déclencher l'événement comme vous le feriez normalement. Une fois l'événement déclenché, une tâche de file d'attente diffusera automatiquement l'événement au pilote de diffusion que vous spécifiez.Nom de diffusion
🎜Laravel utilisera le nom de la classe d'événement par par défaut Comme nom de diffusion pour diffuser l'événement. Cependant, vous pouvez également définir une méthodebroadcastAs
dans la classe d'événement pour personnaliser le nom de la diffusion : 🎜php artisan make:channel OrderChannel
🎜 Si vous utilisez la méthodebroadcastAs
pour personnaliser le nom de la diffusion, vous devez assurez-vous que lorsque vous enregistrez un auditeur, ajoutez un préfixe.
. Cela demandera à Echo de ne pas ajouter l'espace de noms de l'application au début de l'événement : 🎜use App\Broadcasting\OrderChannel; Broadcast::channel('order.{order}', OrderChannel::class);
🎜🎜🎜🎜broadcast Data
🎜Lorsqu'un événement est diffusé, toutes ses propriétéspubliques
sont automatiquement sérialisées et diffusées en tant que charge utile de l'événement. Cela vous permet d'accéder à toutes les propriétés de l'événement dans votre application JavaScript. . Par exemple, si votre événement avait une seule propriété publique$user
contenant un modèle Eloquent, alors la charge utile de diffusion de l'événement serait : 🎜<?php namespace App\Broadcasting; use App\User;use App\Order; class OrderChannel{ /** * 创建一个新的频道实例。 * * @return void */ public function __construct() { // } /** * 认证用户的频道访问权限。 * * @param \App\User $user * @param \App\Order $order * @return array|bool */ public function join(User $user, Order $order) { return $user->id === $order->user_id; } }
🎜Cependant, si vous souhaitez être plus granulaire Pour un contrôle granulaire sur votre charge utile de diffusion, vous pouvez ajouter une méthodebroadcastWith
à votre événement. Cette méthode renvoie un tableau de données que vous souhaitez diffuser en tant que charge utile de l'événement : 🎜event(new ShippingStatusUpdated($update));
🎜🎜🎜🎜🎜🎜File d'attente de diffusion
Par défaut, chaque événement de diffusion sera poussé vers la file d'attente par défaut correspondant à la connexion à la file d'attente par défaut spécifiée dans le fichier de configuration
queue.php
. Vous pouvez définir une propriétébroadcastQueue
dans la classe d'événement pour personnaliser la file d'attente utilisée par le diffuseur. Cette propriété vous oblige à spécifier le nom de la file d'attente que vous souhaitez utiliser lors de la diffusion :queue.php
配置文件中指定的默认队列连接相应的默认队列中。你可以在事件类中定义一个broadcastQueue
属性来自定义广播器所使用的队列。该属性需要你指定广播时你想要用的队列名称:broadcast(new ShippingStatusUpdated($update));
如果你想使用
sync
队列而不是默认队列驱动来广播事件,你可以实现ShouldBroadcastNow
接口而不是ShouldBroadcast
:broadcast(new ShippingStatusUpdated($update))->toOthers();
广播条件
有时,你想在给定条件为 true 的情况下才广播你的事件。你可以通过在事件类中添加一个
broadcastWhen
方法来定义这些条件:axios.post('/task', task) .then((response) => { this.tasks.push(respo });
授权频道
对于私有频道,用户只有被授权之后才能监听。实现过程是用户向你的 Laravel 应用程序发起一个携带频道名称的 HTTP 请求,由你的应用程序判断该用户是否能够监听该频道。在使用 Laravel Echo 时,授权订阅私有频道的 HTTP 请求会自动发送;尽管如此,你仍需定义相应的路由来响应这些请求。
定义授权路由
幸运的是,在 Laravel 中我们可以很容易地定义路由来响应频道授权请求。在 Laravel 自带的
BroadcastServiceProvider
中,你可以看到对Broadcast::routes
方法的调用。该方法会注册/broadcasting/auth
路由来处理授权请求:var socketId = Echo.socketId();
Broadcast::routes
方法会自动将它的路由置入web
中间件组中;不过,如果你想自定义指定的属性,你可以向该方法传递一个路由属性数组:npm install --save laravel-echo pusher-js
自定义授权端点
默认情况下,Echo 将使用
/broadcasting/auth
端点来授权频道访问。 但是,您可以通过将authEndpoint
import Echo from "laravel-echo" window.Echo = new Echo({ broadcaster: 'pusher', key: 'your-pusher-key' });
Si vous souhaitez utiliser la file d'attentesync
au lieu du pilote de file d'attente par défaut pour diffuser les événements, vous pouvez implémenterShouldBroadcastNow
Interface au lieu deShouldBroadcast
:window.Echo = new Echo({ broadcaster: 'pusher', key: 'your-pusher-key', cluster: 'eu', encrypted: true });
broadcast conditions🎜🎜parfois, vous souhaitez diffuser votre événement uniquement si une condition donnée est vraie. Vous pouvez définir ces conditions en ajoutant une méthodebroadcastWhen
à la classe d'événement : 🎜const client = require('pusher-js'); window.Echo = new Echo({ broadcaster: 'pusher', key: 'your-pusher-key', client: client });
🎜🎜🎜🎜Chaîne autorisée
🎜Pour les chaînes privées, les utilisateurs ne peuvent les surveiller que s'ils sont autorisés. Le processus de mise en œuvre consiste en ce que l'utilisateur initie une requête HTTP portant le nom du canal vers votre application Laravel, et votre application détermine si l'utilisateur peut écouter le canal. Lorsque vous utilisez Laravel Echo🎜, les requêtes HTTP pour autoriser les abonnements aux chaînes privées sont envoyées automatiquement, cependant, vous devez toujours définir des routes appropriées pour répondre à ces requêtes ; 🎜🎜🎜🎜🎜🎜Définir les routes d'autorisation🎜🎜Heureusement, dans Laravel, nous pouvons facilement définir des routes pour répondre demandes d'autorisation de canal. Dans leBroadcastServiceProvider
fourni avec Laravel, vous pouvez voir l'appel à la méthodeBroadcast::routes
. Cette méthode enregistrera la route/broadcasting/auth
pour gérer les demandes d'autorisation : 🎜Echo.channel('orders') .listen('OrderShipped', (e) => { console.log(e.order.name); });
🎜 La méthodeBroadcast::routes
placera automatiquement ses routes dansweb code code> dans le groupe middleware ; cependant, si vous souhaitez personnaliser les attributs spécifiés, vous pouvez transmettre un tableau d'attributs de routage à cette méthode : 🎜
Echo.private('orders') .listen(...) .listen(...) .listen(...);
🎜< h4> Point de terminaison d'autorisation personnalisé🎜Par défaut, Echo utilisera le point de terminaison/broadcasting/auth
pour autoriser l'accès au canal. Cependant, vous pouvez spécifier votre propre point de terminaison d'autorisation en transmettant l'option de configurationauthEndpoint
à l'instance Echo : 🎜Echo.leaveChannel('orders');
🎜🎜🎜🎜🎜🎜Définir le rappel d'autorisation
Ensuite, nous devons définir la logique qui gère réellement l'autorisation du canal. Cette logique est complétée dans le fichier
routes/channels.php
fourni avec l'application. Dans ce fichier, vous pouvez utiliser la méthodeBroadcast::channel
pour enregistrer le rappel d'autorisation du canal :routes/channels.php
文件中完成。在这个文件中,你可以使用Broadcast::channel
方法来注册频道授权回调:Echo.leave('orders');
channel
方法接收两个参数:频道名称和一个回调函数,该回调通过返回true
或者false
来表示用户是否被授权监听该频道。所有的授权回调接收当前认证用户作为第一个参数,任何额外的通配符参数作为后续参数。在本例中,我们使用
{orderId}
占位符来表示频道名称的 「ID」 部分是通配符。授权回调模型绑定
就像 HTTP 路由一样,频道路由也可以利用显式或隐式 路由模型绑定 。例如,你可以请求接收一个真正的
Order
模型实例,而不是字符串或数字类型的 order ID:window.Echo = new Echo({ broadcaster: 'pusher', key: 'your-pusher-key', namespace: 'App.Other.Namespace' });
授权回调验证
私有频道和在线广播频道通过应用程序的默认授权验证对当前用户身份进行验证。 如果用户未经过授权验证,则会自动拒绝通道授权,并且永远不会执行授权回调。 但是,您可以分配多个自定义防护,以便在必要时对传入请求进行身份验证:
Echo.channel('orders') .listen('.Namespace.Event.Class', (e) => { // });
定义频道类
如果你的应用程序用到了许多不同的频道,你的
routes/channels.php
文件可能会变得很庞大。所以,你可以使用频道类来代替使用闭包授权频道。要生成一个频道类,请使用make:channel
Artisan 命令。该命令会在App/Broadcasting
目录中放置一个新的频道类。Broadcast::channel('chat.{roomId}', function ($user, $roomId) { if ($user->canJoinRoom($roomId)) { return ['id' => $user->id, 'name' => $user->name]; } });
接下来,在你的
routes/channels.php
文件中注册你的频道:Echo.join(`chat.${roomId}`) .here((users) => { // }) .joining((user) => { console.log(user.name); }) .leaving((user) => { console.log(user.name); });
最后,你可以将频道的授权逻辑放入频道类的
join
方法中。该join
/** * 获得事件广播的频道。 * * @return Channel|array */ public function broadcastOn(){ return new PresenceChannel('room.'.$this->message->room_id); }
La méthodechannel
reçoit deux paramètres : le nom du canal et un rappel fonction, ce rappel indique si l'utilisateur est autorisé à écouter la chaîne en renvoyanttrue
oufalse
.Tous les rappels d'autorisation reçoivent l'utilisateur authentifié actuel comme premier paramètre, et tous les paramètres génériques supplémentaires comme paramètres suivants. Dans cet exemple, nous utilisons l'espace réservé
{orderId}
pour indiquer que la partie « ID » du nom de la chaîne est un caractère générique.Liaison de modèle de rappel d'autorisation
Tout comme le routage HTTP, le routage de canal peut également tirer parti de la liaison de modèle de routage explicite ou implicite. Par exemple, vous pouvez demander à recevoir une véritable instance du modèle
Order
au lieu d'une chaîne ou d'un identifiant de commande numérique :broadcast(new NewMessage($message)); broadcast(new NewMessage($message))->toOthers();
< h4> Vérification du rappel d'autorisationLes chaînes privées et les chaînes de diffusion en ligne vérifient l'identité actuelle de l'utilisateur via la vérification d'autorisation par défaut de l'application. Si l'utilisateur n'est pas authentifié pour l'autorisation, l'autorisation du canal est automatiquement refusée et le rappel d'autorisation n'est jamais exécuté. Cependant, vous pouvez attribuer plusieurs gardes personnalisés pour authentifier les demandes entrantes lorsque cela est nécessaire : 🎜🎜Echo.join(`chat.${roomId}`) .here(...) .joining(...) .leaving(...) .listen('NewMessage', (e) => { // });
🎜 🎜Définissez les classes de canaux🎜🎜Si votre application utilise de nombreux canaux différents, votre fichierroutes/channels.php
peut devenir très volumineux. Ainsi, vous pouvez utiliser des classes de canaux au lieu d'utiliser des fermetures pour autoriser les canaux. Pour générer une classe de canal, utilisez la commandemake:channel
Artisan. Cette commande place une nouvelle classe de canal dans le répertoireApp/Broadcasting
. 🎜Echo.private('chat') .whisper('typing', { name: this.user.name });
🎜Ensuite, enregistrez votre chaîne dans votre fichierroutes/channels.php
: 🎜Echo.private('chat') .listenForWhisper('typing', (e) => { console.log(e.name); });
🎜Enfin, vous pouvez mettre la logique d'autorisation de la chaîne dans lejoin< de la classe /code> de la chaîne. méthode. La méthode
join
contiendra la même logique que celle que vous mettriez normalement dans la fermeture d'autorisation de canal. Bien sûr, vous pouvez également profiter de la liaison de modèle de canal : 🎜Echo.private(`App.User.${userId}`) .notification((notification) => { console.log(notification.type); });
🎜🎜{Note} Comme beaucoup d'autres classes dans Laravel, les classes de canal sont automatiquement résolues via le conteneur de services. Par conséquent, vous pouvez indiquer les dépendances requises sur votre classe de canal dans son constructeur. 🎜🎜🎜🎜🎜🎜🎜🎜Événement de diffusion
Après avoir défini un événement et l'avoir marqué pour implémenter l'interface
rrreeeShouldBroadcast
, il ne vous reste plus qu'à déclencher l'événement via la fonctionevent
. Le répartiteur d'événements reconnaîtra les événements marqués avec l'interfaceShouldBroadcast
et les placera dans la file d'attente pour diffusion :ShouldBroadcast
接口之后,你所要做的仅仅是通过event
函数来触发该事件。事件分发器会识别出标记了实现ShouldBroadcast
接口的事件,并将其推送到队列中进行广播:只广播给他人
当创建一个会用到事件广播的应用程序时,你可以使用
rrreeebroadcast
函数来代替event
。和event
函数一样,broadcast
函数将事件分发到服务端监听器:不过,
rrreeebroadcast
函数还有一个允许你将当前用户排除在广播接收者之外的toOthers
方法:为了更好地理解什么时候使用
rrreeetoOthers
方法,让我们假设有一个任务列表的应用程序,用户可以通过输入任务名来新建任务。要新建任务,你的应用程序需要发起一个请求到一个/task
路由,该路由会广播任务的创建,并返回新任务的 JSON 响应。当你的 JavaScript 应用程序从路由收到响应后,它会直接将新任务插入到任务列表中,就像这样:然而,别忘了,我们还广播了任务的创建。如果你的 JavaScript 应用程序正在监听该事件以便添加任务至任务列表,任务列表中将出现重复的任务:一个来自路由响应,另一个来自广播。你可以通过使用
toOthers
方法告知广播器不要将事件广播到当前用户来解决这个问题。{注} 为了能调用
toOthers
方法,你的事件必须使用IlluminateBroadcastingInteractsWithSockets
trait 。配置
当你初始化 Laravel Echo 实例的时候,一个套接字 ID 会被分配到该连接。如果你使用了 Vue 和 Axios ,该套接字 ID 会自动地以
X-Socket-ID
头的方式添加到每一个传出请求中。那么,当你调用toOthers
方法时,Laravel 会从请求头中取出套接字 ID ,并告知广播器不要广播任何消息到带有这个套接字 ID 的连接上。你如果你没有使用 Vue 和 Axios ,则需要手动配置 JavaScript 应用程序来发送
X-Socket-ID
请求头。你可以用Echo.socketId
rrreeeDiffuser uniquement à d'autres
Lors de la création d'une application qui utilise la diffusion d'événements, vous pouvez utiliser la fonctionbroadcast
pour remplacerevent< /code>. Comme la fonction
event
, la fonctionbroadcast
distribue les événements aux auditeurs côté serveur :rrreeeCependant, la fonctionbroadcast
a également une fonction supplémentaire qui vous permet d'utiliser la méthodetoOthers
qui exclut l'utilisateur actuel d'être un récepteur de diffusion :rrreee
Pour mieux comprendre quand utiliser la méthodetoOthers
, supposons que nous ayons une tâche programme d'application de liste, les utilisateurs peuvent créer de nouvelles tâches en entrant le nom de la tâche. Pour créer une nouvelle tâche, votre application fait une requête à une route/task
, qui diffuse la création de la tâche et renvoie une réponse JSON pour la nouvelle tâche. Lorsque votre application JavaScript recevra la réponse de la route, elle insérera la nouvelle tâche directement dans la liste des tâches, comme ceci :{Note} Afin d'appeler la méthode
toOthers
, votre événement doit utiliser le traitIlluminateBroadcastingInteractsWithSockets
.Configuration
🎜Lorsque vous initialisez une instance de Laravel Echo, un ID de socket sera attribué à la connexion. Si vous utilisez Vue🎜 et Axios🎜, cet ID de socket sera automatiquement ajouté à chaque sortie. requête en tant qu'en-têteX-Socket-ID
. Ensuite, lorsque vous appelez la méthodetoOthers
, Laravel retirera l'ID de socket de l'en-tête de la requête et indiquera au diffuseur de ne diffuser aucun message à la connexion avec cet ID de socket. 🎜🎜Si vous n'utilisez pas Vue et Axios, vous devrez configurer manuellement votre application JavaScript pour envoyer l'en-tête de requêteX-Socket-ID
. Vous pouvez utiliser la méthodeEcho.socketId
pour obtenir l'ID du socket : 🎜rrreee🎜🎜🎜🎜🎜🎜🎜Recevoir la diffusion🎜🎜🎜🎜🎜🎜🎜Installer Laravel Echo
Laravel Echo est une bibliothèque JavaScript Avec cette bibliothèque, il devient très simple de s'abonner aux chaînes et d'écouter les événements diffusés par Laravel. Vous pouvez installer Echo via le gestionnaire de packages NPM. Dans ce cas, puisque nous utiliserons le diffuseur Pusher, nous installerons également le package
rrreeepusher-js
:pusher-js
包:安装好 Echo 之后,你就可以在应用程序的 JavaScript 中创建一个全新的 Echo 实例。做这件事的一个理想的地方是在 Laravel 框架自带的
rrreeeresources/js/bootstrap.js
文件的底部:当你使用
rrreeepusher
连接器来创建一个 Echo 实例的时候,还可以指定cluster
以及连接是否需要加密:使用现有客户端实例
如果您已经有一个希望 Echo 使用的 Pusher 或 Socket.io 客户端实例,您可以通过
rrreeeclient
配置选项将其传递给 Echo:对事件进行监听
安装并实例化 Echo 之后, 你就可以开始监听事件广播了。首先,使用
rrreeechannel
方法获取一个频道实例,然后调用listen
方法来监听指定的事件:如果你想监听私有频道上的事件,请使用
rrreeeprivate
方法。你可以通过链式调用listen
方法来监听单个频道上的多个事件:退出频道
要离开频道,您可以在 Echo 实例上调用
rrreeeleaveChannel
方法:如果您想离开私有频道和在线频道,您可以调用
rrreeeleave
方法:命名空间
你可能已经注意到在上面的例子中,我们并没有为事件类指定完整的命名空间。这是因为 Echo 会默认事件都在
rrreeeAppEvents
命名空间下。不过,你可以在实例化 Echo 时传递一个namespace
配置项来指定根命名空间:另外,你可以在使用 Echo 订阅事件的时候为事件类加上
Après avoir installé Echo, vous pouvez en créer un nouveau dans l'instance JavaScript Echo de votre application. Un endroit idéal pour le faire est au bas du fichier.
rrreeeresources/js/bootstrap.js
fourni avec le framework Laravel :Utiliser un Instance client client existante
Si vous disposez déjà d'une instance client Pusher ou Socket.io que vous souhaitez qu'Echo utilise, vous pouvez la transmettre à Echo via l'option de configurationrrreeeclient
:Écouter les événementsAprès avoir installé et instancié Echo, vous pouvez commencer à écouter les diffusions d'événements. Tout d'abord, utilisez la méthode
rrreeechannel
pour obtenir une instance de canal, puis appelez la méthodelisten
pour écouter l'événement spécifié :Si vous souhaitez écouter les événements sur une chaîne privée, veuillez utiliser la méthode < code>privée. Vous pouvez écouter plusieurs événements sur une seule chaîne en enchaînant la méthoderrreee🎜🎜🎜listen
:🎜🎜Quitter la chaîne🎜🎜Pour quitter une chaîne, vous pouvez appeler la méthodeleaveChannel
sur l'instance Echo : 🎜rrreee🎜Si vous souhaitez quitter les chaînes privées et les chaînes en ligne, vous pouvez appelez la méthodeleave
: 🎜rrreee🎜🎜🎜🎜🎜namespaces🎜🎜Vous avez peut-être remarqué que dans Dans l'exemple ci-dessus, nous n'avons pas spécifié l'espace de noms complet pour la classe d'événement. En effet, Echo placera par défaut les événements sous l'espace de nomsAppEvents
. Cependant, vous pouvez transmettre un élément de configurationnamespace
pour spécifier l'espace de noms racine lors de l'instanciation d'Echo : 🎜rrreee🎜 De plus, vous pouvez ajouterà la classe d'événement lorsque vous utilisez Echo pour vous abonner à des événements <. /code> préfixe. Cela vous permet de spécifier le nom complet de la classe : 🎜rrreee🎜🎜🎜🎜🎜🎜🎜Canaux de présence 🎜🎜Les canaux de présence s'appuient sur la sécurité des chaînes privées et offrent des fonctionnalités supplémentaires : savoir qui est abonné à la chaîne de la chaîne. Cela facilite grandement la création d'applications collaboratives puissantes, par exemple lorsqu'un utilisateur parcourt une page, en informant les autres utilisateurs qui parcourent la même page. 🎜🎜🎜🎜🎜🎜🎜
etCanaux de présence autorisés
Tous les canaux de présence sont également des canaux privés, par conséquent, les utilisateurs doivent être autorisés avant de pouvoir accéder à ; Cependant, lors de la définition d'une fonction de rappel d'autorisation pour un canal de présence, si un utilisateur a déjà rejoint le canal,
true
ne doit pas être renvoyé, mais un tableau d'informations sur l'utilisateur doit être renvoyé.true
,而应该返回一个关于该用户信息的数组。由授权回调函数返回的数据能够在你的 JavaScript 应用程序中被 presence 频道事件监听器所使用。如果用户没有被授权加入该 presence 频道,那么你应该返回
rrreeefalse
或者null
:加入 Presence 频道
你可以使用 Echo 的
rrreeejoin
方法来加入 presence 频道。join
方法会返回一个实现了PresenceChannel
的对象,通过暴露listen
方法,允许你订阅here
、joining
和leaving
事件。here
回调函数会在你成功加入频道后被立即执行,并接收一个包含其他所有当前订阅该频道的用户的用户信息数组 。joining
方法会在新用户加入频道时被执行,而leaving
方法会在用户退出频道时被执行。广播到 Presence 频道
Presence 频道可以像公开和私有频道一样接收事件。使用一个聊天室的例子,我们可能想把
rrreeeNewMessage
事件广播到聊天室的 presence 频道。要实现它,我们将从事件的broadcastOn
方法中返回一个PresenceChannel
实例:就像公开或私有事件, presence 频道事件也可以使用
rrreeebroadcast
函数来广播。同样的,你也可以使用toOthers
方法将当前用户排除在广播接收者之外:你可以通过 Echo 的
Les données renvoyées par la fonction de rappel d'autorisation peuvent être utilisées par les écouteurs d'événements du canal de présence dans votre application JavaScript. Si l'utilisateur n'est pas autorisé à rejoindre le canal de présence, alors vous devez renvoyerlisten
false
ounull
: < div name="a2f9d5" data-unique="a2f9d5">Rejoignez le canal de présence🎜🎜Vous pouvez utiliser la méthodejoin
d'Echo pour rejoindre le canal de présence. La méthodejoin
renvoie un objet qui implémentePresenceChannel
et expose la méthodelisten
, vous permettant de vous abonner àici
, Événements < code>rejoindrequitter
. 🎜rrreee🎜ici
La fonction de rappel sera exécutée immédiatement après avoir rejoint la chaîne avec succès et recevra un tableau d'informations utilisateur contenant tous les autres utilisateurs actuellement abonnés à la chaîne. La méthodejoining
sera exécutée lorsqu'un nouvel utilisateur rejoint le canal, et la méthodeleaving
sera exécutée lorsque l'utilisateur quittera le canal.
🎜🎜🎜🎜Diffusion vers les canaux de présence🎜🎜Les canaux de présence peuvent être aussi publics et Les chaînes privées reçoivent également des événements. En utilisant l'exemple d'un salon de discussion, nous pourrions souhaiter diffuser l'événementNewMessage
sur le canal de présence du salon de discussion. Pour l'implémenter, nous renverrons une instancePresenceChannel
à partir de la méthodebroadcastOn
de l'événement : 🎜rrreee🎜Tout comme les événements publics ou privés, les événements du canal de présence peuvent également être utilisésfonction de diffusion
pour diffuser. De même, vous pouvez également utiliser la méthodetoOthers
pour exclure l'utilisateur actuel des récepteurs de diffusion : 🎜rrreee🎜Vous pouvez écouter l'événement de jointure via la méthodelisten
d'Echo : 🎜 rrreee🎜 🎜🎜🎜🎜🎜Événements client
{Remarque} Lorsque vous utilisez Pusher, si vous souhaitez envoyer des événements client, vous devez activer l'option "Événements client" dans la section "Paramètres de l'application" du App Backend.
Parfois, vous souhaiterez peut-être diffuser un événement à d'autres clients connectés sans en avertir votre application Laravel. Ceci est particulièrement utile lors de la gestion des notifications pour des tâches de « saisie en cours », par exemple pour alerter les utilisateurs de votre application qu'un autre utilisateur est en train de saisir des informations sur un écran donné.
Vous pouvez utiliser la méthode
rrreeewhisper
d'Echo pour diffuser les événements client :whisper
方法来广播客户端事件:你可以使用
rrreeelistenForWhisper
方法来监听客户端事件:消息通知
通过与将事件广播与 消息通知 配对,你的 JavaScript 应用程序可以在不刷新页面的情况下接收新的消息通知。在此之前,请确保你已经读过了如何使用 广播通知频道 的文档。
配置好使用广播频道的消息通知后,你可以使用 Echo 的
rrreeenotification
方法来监听广播事件。谨记,频道名称应该和接收消息通知的实体类名相匹配:在本例中,所有通过
Vous pouvez utiliser la méthodebroadcast
频道发送到AppUser
实例的消息通知都会被回调接收。一个针对App.User.{id}
频道的授权回调函数已经包含在 Laravel 框架内置的BroadcastServiceProvider
rrreeelistenForWhisper
pour écouter les événements client : 🎜Notifications de messages🎜🎜En associant les diffusions d'événements aux notifications de messages, votre application JavaScript peut mettre à jour la page sans actualiser la page. Recevez des notifications de nouveaux messages. Avant de faire cela, assurez-vous d'avoir lu la documentation sur la façon d'utiliser les canaux de notification de diffusion. 🎜🎜Après avoir configuré la notification de message à l'aide du canal de diffusion, vous pouvez utiliser la méthodenotification
d'Echo pour écouter les événements de diffusion. N'oubliez pas que le nom du canal doit correspondre au nom de classe de l'entité recevant les notifications : 🎜rrreee🎜Dans ce cas, toutes les notifications envoyées à l'instanceAppUser
via le canalbroadcast
seront reçu par le rappel. Une fonction de rappel d'autorisation pour le canalApp.User.{id}
est déjà incluse dans leBroadcastServiceProvider
intégré du framework Laravel. 🎜🎜Cet article a été publié pour la première fois sur le site 🎜LearnKu.com🎜. 🎜🎜