找回密码
 立即注册
首页 业界区 安全 Laravel11 从0开发 Swoole-Reverb 扩展包(五) - Larav ...

Laravel11 从0开发 Swoole-Reverb 扩展包(五) - Laravel Echo 介绍

洪势 2025-6-1 20:56:09
前情提要

上一节我们完整的梳理了整个通信过程,接下来我们需要来看前端的处理过程。
Laravel Echo

Laravel Echo 是一个 JavaScript 库,它让您可以轻松订阅频道并监听服务器端广播驱动程序广播的事件。您可以通过 NPM 包管理器安装 Echo。在此示例中,我们还将安装 pusher-js 包,因为 Reverb 使用 Pusher 协议进行 WebSocket 订阅、频道和消息
安装
  1. npm install --save-dev laravel-echo pusher-js
  2. yarn add --save-dev laravel-echo pusher-js
复制代码
安装 Echo 后,您就可以在应用程序的 JavaScript 中创建一个新的 Echo 实例。执行此操作的最佳位置是 Laravel 框架附带的 resources/js/bootstrap.js 文件的底部。默认情况下,此文件中已包含一个示例 Echo 配置 - 您只需取消注释并将广播器配置选项更新为 reverb:
  1. import Echo from 'laravel-echo';
  2. import Pusher from 'pusher-js';
  3. window.Pusher = Pusher;
  4. window.Echo = new Echo({
  5.     broadcaster: 'reverb',
  6.     key: import.meta.env.VITE_REVERB_APP_KEY,
  7.     wsHost: import.meta.env.VITE_REVERB_HOST,
  8.     wsPort: import.meta.env.VITE_REVERB_PORT,
  9.     wssPort: import.meta.env.VITE_REVERB_PORT,
  10.     forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
  11.     enabledTransports: ['ws', 'wss'],
  12. });
复制代码
监听事件

安装并实例化 Laravel Echo 后,您就可以开始监听从 Laravel 应用程序广播的事件了。首先,使用 channel 方法检索通道实例,然后调用 listen 方法来监听指定的事件::
  1. Echo.channel(`orders.${this.order.id}`)
  2.     .listen('OrderShipmentStatusUpdated', (e) => {
  3.         console.log(e.order.name);
  4.     });
复制代码
如果您想在私有频道上监听事件,请改用私有方法。您可以继续链接调用 listen 方法以在单个频道上监听多个事件:
  1. Echo.private(`orders.${this.order.id}`)
  2.     .listen(/* ... */)
  3.     .listen(/* ... */)
  4.     .listen(/* ... */);
复制代码
停止监听事件

如果您想在不离开频道的情况下停止监听给定事件,您可以使用 stopListening 方法:
  1. Echo.private(`orders.${this.order.id}`)
  2.     .stopListening('OrderShipmentStatusUpdated')
复制代码
离开频道

要离开频道,您可以调用 Echo 实例上的 leaveChannel 方法:
  1. Echo.leaveChannel(`orders.${this.order.id}`);
复制代码
如果你想离开一个频道以及其关联的私人频道和在线频道,你可以调用 leave 方法:
  1. Echo.leave(`orders.${this.order.id}`);
复制代码
命名空间

您可能已经注意到,在上面的示例中,我们没有为事件类指定完整的 App\Events 命名空间。这是因为 Echo 会自动假定事件位于 App\Events 命名空间中。但是,您可以在实例化 Echo 时通过传递命名空间配置选项来配置根命名空间:
  1. window.Echo = new Echo({
  2.     broadcaster: 'pusher',
  3.     // ...
  4.     namespace: 'App.Other.Namespace'
  5. });
复制代码
或者,您可以在使用 Echo 订阅事件类时为其添加前缀 .。这样您就可以始终指定完全限定的类名:
  1. Echo.channel('orders')
  2.     .listen('.Namespace\\Event\\Class', (e) => {
  3.         // ...
  4.     });
复制代码
Presence Channels

在线频道以私人频道的安全性为基础,同时还提供了了解频道订阅者的功能。这样可以轻松构建强大的协作应用程序功能,例如当其他用户正在查看同一页面时通知用户或列出聊天室的成员。
授权状态通道

所有在线频道也是私有频道;因此,用户必须获得授权才能访问它们。但是,在为在线频道定义授权回调时,如果用户被授权加入频道,则不会返回 true。相反,您应该返回有关用户的数据数组。
授权回调返回的数据将提供给 JavaScript 应用程序中的在线频道事件侦听器。如果用户未被授权加入在线频道,则应该返回 false 或 null:
  1. use App\Models\User;
  2. Broadcast::channel('chat.{roomId}', function (User $user, int $roomId) {
  3.     if ($user->canJoinRoom($roomId)) {
  4.         return ['id' => $user->id, 'name' => $user->name];
  5.     }
  6. });
复制代码
连接在线频道

要加入状态频道,您可以使用 Echo 的 join 方法。join 方法将返回 PresenceChannel 实现,它除了公开 listen 方法外,还允许您订阅当前状态、加入和离开事件.
  1. Echo.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.     });
复制代码
成功加入频道后,将立即执行此处的回调,并将收到一个数组,其中包含当前订阅该频道的所有其他用户的用户信息。当新用户加入频道时,将执行加入方法,而当用户离开频道时,将执行离开方法。当身份验证端点返回除 200 以外的 HTTP 状态代码或解析返回的 JSON 时出现问题时,将执行错误方法。
向 Presence 频道广播
Presence 频道可以像公共或私人频道一样接收事件。使用聊天室的示例,我们可能希望将 NewMessage 事件广播到房间的 Presence 频道。为此,我们将从事件的 broadcastOn 方法返回 PresenceChannel 的一个实例:
  1. /**
  2. * Get the channels the event should broadcast on.
  3. *
  4. * @return array<int, \Illuminate\Broadcasting\Channel>
  5. */
  6. public function broadcastOn(): array
  7. {
  8.     return [
  9.         new PresenceChannel('chat.'.$this->message->room_id),
  10.     ];
  11. }
复制代码
与其他事件一样,您可以使用广播助手和 toOthers 方法来排除当前用户接收广播:
  1. broadcast(new NewMessage($message));
  2. broadcast(new NewMessage($message))->toOthers();
复制代码
与其他类型的事件一样,您可以使用 Echo 的 listen 方法监听发送到存在通道的事件:
  1. Echo.join(`chat.${roomId}`)
  2.     .here(/* ... */)
  3.     .joining(/* ... */)
  4.     .leaving(/* ... */)
  5.     .listen('NewMessage', (e) => {
  6.         // ...
  7.     });
复制代码
客户端事件

有时您可能希望将事件广播给其他连接的客户端,而无需访问您的 Laravel 应用程序。这对于“输入”通知等情况特别有用,在这种情况下,您希望提醒应用程序的用户另一个用户正在给定的屏幕上输入消息。
要广播客户端事件,您可以使用 Echo 的 whisper 方法:
  1. Echo.private(`chat.${roomId}`)
  2.     .whisper('typing', {
  3.         name: this.user.name
  4.     });
复制代码
要监听客户端事件,你可以使用 listenForWhisper 方法:
  1. Echo.private(`chat.${roomId}`)
  2.     .listenForWhisper('typing', (e) => {
  3.         console.log(e.name);
  4.     });
复制代码
通知

通过将事件广播与通知配对,您的 JavaScript 应用程序可以在新通知发生时接收它们,而无需刷新页面。在开始之前,请务必阅读有关使用广播通知渠道的文档。
配置通知以使用广播渠道后,您可以使用 Echo 的通知方法监听广播事件。请记住,渠道名称应与接收通知的实体的类名匹配:
  1. Echo.private(`App.Models.User.${userId}`)
  2.     .notification((notification) => {
  3.         console.log(notification.type);
  4.     });
复制代码
在此示例中,通过广播渠道发送到 App\Models\User 实例的所有通知都将由回调接收。App.Models.User.{id} 渠道的渠道授权回调包含在应用程序的 routes/channels.php 文件中。
以上内容翻译自laravel官方文档。
提供一个简单的页面案例

这个页面实现了广播事件监听、客户端发送,客户端监听等功能
  1. <template>
  2.     <Head title="聊天"/>
  3.    
  4.         
  5.             
  6.             
  7.                 联系人
  8.             
  9.             
  10.             
  11.                
  12.                
  13.                     {{ currentDate }}
  14.                
  15.                
  16.                
  17.                     
  18.                     
  19.                         
  20.                             {{ message.content }}
  21.                             <button v-if="message.type === 'coupon'"
  22.                                     
  23.                                     type="button"
  24.                                     @click="receiveCoupon">
  25.                                 领取
  26.                             </button>
  27.                         
  28.                     
  29.                     
  30.                         ⚠️ {{ message.content }}
  31.                     
  32.                     
  33.                     
  34.                         
  35.                         
  36.                             {{ message.author.charAt(0) }}
  37.                         
  38.                         
  39.                            
  40.                             {{ message.author }}
  41.                            
  42.                            
  43.                                 {{ message.content }}
  44.                            
  45.                            
  46.                            
  47.                                 {{ formatMessageTime(message.timestamp) }}
  48.                            
  49.                         
  50.                         
  51.                         
  52.                             {{ user.name.charAt(0) }}
  53.                         
  54.                     
  55.                
  56.             
  57.             
  58.             
  59.                
  60.                     <input
  61.                         v-model="newMessage"
  62.                         @keydown.enter="sendMessage"
  63.                         placeholder="发送消息..."
  64.                         
  65.                     />
  66.                     <button
  67.                         @click="sendMessage"
  68.                         v-if="canSend"
  69.                         
  70.                         :
  71.                     >
  72.                         发送
  73.                     </button>
  74.                
  75.             
  76.         
  77.     </AuthenticatedLayout>
  78.     <footer >
  79.         Laravel{{ laravelVersion }}-PHP{{ phpVersion }}
  80.     </footer>
  81. </template>
复制代码
1.png

[code][/code]
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册