国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Manual Dokumentasi Cina Laravel 5.8 / 廣播系統(tǒng)

廣播系統(tǒng)

廣播系統(tǒng)


廣播系統(tǒng)

簡介

在現(xiàn)代的 web 應(yīng)用程序中, WebSockets 被用來實(shí)現(xiàn)實(shí)時、即時更新的用戶接口。當(dāng)服務(wù)器上的數(shù)據(jù)更新后,更新信息會通過 WebSocket 連接發(fā)送到客戶端等待處理。相比于不停地輪詢應(yīng)用程序,這是一種更加可靠和高效的選擇。

為了幫助你構(gòu)建這類應(yīng)用, Laravel 將通過 WebSocket 連接來使「廣播」 事件 變得更加輕松。 廣播 Laravel 事件允許你在服務(wù)端和客戶端 JavaScript 應(yīng)用程序間共享相同的事件名。

{注} 在深入了解事件廣播之前,請確認(rèn)你已閱讀所有關(guān)于 Laravel 事件和監(jiān)聽器 的文檔。

配置

所有關(guān)于事件廣播的配置都保存在 config/broadcasting.php 配置文件中。 Laravel 自帶了幾個廣播驅(qū)動: Pusher 、 Redis , 和一個用于本地開發(fā)與調(diào)試的 log 驅(qū)動。另外,還有一個 null 驅(qū)動允許你完全關(guān)閉廣播系統(tǒng)。每一個驅(qū)動的示例配置都可以在 config/broadcasting.php 配置文件中找到。

廣播服務(wù)提供者

在對事件進(jìn)行廣播之前,你必須先注冊 App\Providers\BroadcastServiceProvider 。對于一個新建的 Laravel 應(yīng)用程序,你只需要在 config/app.php 配置文件的 providers 數(shù)組中取消對該提供者的注釋即可。該提供者將允許你注冊廣播授權(quán)路由和回調(diào)。

CSRF 令牌

Laravel Echo 需要訪問當(dāng)前會話的 CSRF 令牌。你應(yīng)當(dāng)驗(yàn)證你的應(yīng)用程序的 head HTML 元素是否定義了包含 CSRF 令牌的 meta 標(biāo)簽:

<meta name="csrf-token" content="{{ csrf_token() }}">

對驅(qū)動的要求

Pusher

如果你使用 Pusher 來對事件進(jìn)行廣播,請用 Composer 包管理器來安裝 Pusher PHP SDK :

composer require pusher/pusher-php-server "~3.0"

然后,你需要在 config/broadcasting.php 配置文件中配置你的 Pusher 證書。該文件中已經(jīng)包含了一個 Pusher 示例配置,你可以快速地指定你的 Pusher key 、secret 和 application ID。 config/broadcasting.php 文件的 pusher 配置項(xiàng)同時也允許你指定 Pusher 支持的額外 options ,例如 cluster:

'options' => [ 
   'cluster' => 'eu',    
   'encrypted' => true
 ],

當(dāng) Pusher 和 Laravel Echo 一起使用時,你應(yīng)該在 resources/assets/js/bootstrap.js 文件中實(shí)例化 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 的 發(fā)布 / 訂閱 特性來廣播消息;盡管如此,你仍需將它與能夠從 Redis 接收消息的 WebSocket 服務(wù)器配對使用以便將消息廣播到你的 WebSocket 頻道上去。

當(dāng) Redis 廣播器發(fā)布一個事件的時候,該事件會被發(fā)布到它指定的頻道上去,傳輸?shù)臄?shù)據(jù)是一個采用 JSON 編碼的字符串。該字符串包含了事件名、 data 數(shù)據(jù)和生成該事件 socket ID 的用戶(如果可用的話)。

Socket.IO

如果你想將 Redis 廣播器 和 Socket.IO 服務(wù)器進(jìn)行配對,你需要在你的應(yīng)用程序中引入 Socket.IO JavaScript 客戶端庫。你可以通過 NPM 包管理器進(jìn)行安裝:

npm install --save socket.io-client

然后,你需要在實(shí)例化 Echo 時指定 socket.io 連接器和 host 。

import Echo from "laravel-echo"window.io = require('socket.io-client');
window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
 });

最后,你需要運(yùn)行一個與 Laravel 兼容的 Socket.IO 服務(wù)器。 Laravel 官方并沒有內(nèi)置 Socket.IO 服務(wù)器實(shí)現(xiàn);不過,可以選擇一個由社區(qū)驅(qū)動維護(hù)的項(xiàng)目 tlaverdure/laravel-echo-server ,目前托管在 GitHub 。

對隊(duì)列的要求

在開始廣播事件之前,你還需要配置和運(yùn)行 隊(duì)列監(jiān)聽器 。所有的事件廣播都是通過隊(duì)列任務(wù)來完成的,因此應(yīng)用程序的響應(yīng)時間不會受到明顯影響。

概念綜述

Laravel 的事件廣播允許你使用基于驅(qū)動的 WebSockets 將服務(wù)端的 Laravel 事件廣播到客戶端的 JavaScript 應(yīng)用程序。當(dāng)前的 Laravel 自帶了 Pusher 和 Redis 驅(qū)動。通過使用 Laravel Echo 的 Javascript 包,我們可以很方便地在客戶端消費(fèi)事件。

事件通過「頻道」來廣播,這些頻道可以被指定為公開或私有的。任何訪客都可以不經(jīng)授權(quán)或認(rèn)證訂閱一個公開頻道;然而,如果想要訂閱一個私有頻道,那么該用戶必須通過認(rèn)證,并獲得該頻道的授權(quán)。

使用示例程序

在深入了解事件廣播的每個組件之前,讓我們先用一個電子商務(wù)網(wǎng)站作為例子來概覽一下。我們不會討論配置 Pusher 或者 Laravel Echo 的細(xì)節(jié),這些會在本文檔的其它章節(jié)里詳細(xì)討論。

在我們的應(yīng)用程序中,我們假設(shè)有一個允許用戶查看訂單配送狀態(tài)的頁面。有一個 ShippingStatusUpdated 事件會在配送狀態(tài)更新時被觸發(fā):

event(new ShippingStatusUpdated($update));

ShouldBroadcast 接口

當(dāng)用戶在查看自己的訂單時,我們不希望他們必須通過刷新頁面才能看到狀態(tài)更新。我們希望一旦有更新時就主動將更新信息廣播到客戶端。所以,我們必須標(biāo)記 ShippingStatusUpdated 事件實(shí)現(xiàn) ShouldBroadcast 接口。這會讓 Laravel 在事件被觸發(fā)時廣播該事件:

<?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{  
     /**
     * 有關(guān)配送狀態(tài)更新的信息。
     *
     * @var string
     */  
   public $update;
  }

ShouldBroadcast 接口要求事件定義一個 broadcastOn 方法。該方法負(fù)責(zé)指定事件被廣播到哪些頻道。在(通過 Artisan 命令)生成的事件類中,一個空的 broadcastOn 方法已經(jīng)被預(yù)定義好了,所以我們只需要完成其細(xì)節(jié)即可。我們希望只有訂單的創(chuàng)建者能夠看到狀態(tài)的更新,所以我們要把該事件廣播到與這個訂單綁定的私有頻道上去:

/**
 * 獲取事件應(yīng)該廣播的頻道。
 *
 * @return array
 */
 public function broadcastOn(){ 
    return new PrivateChannel('order.'.$this->update->order_id);
 }

授權(quán)頻道

記住,用戶只有在被授權(quán)之后才能監(jiān)聽私有頻道。我們可以在 routes/channels.php 文件中定義頻道的授權(quán)規(guī)則。在本例中,我們需要對視圖監(jiān)聽私有 order.1 頻道的所有用戶進(jìn)行驗(yàn)證,確保只有訂單真正的創(chuàng)建者才能監(jiān)聽:

Broadcast::channel('order.{orderId}', function ($user, $orderId) { 
   return $user->id === Order::findOrNew($orderId)->user_id;
});

channel 方法接收兩個參數(shù):頻道名稱和一個回調(diào)函數(shù),該回調(diào)通過返回 true 或者 false 來表示用戶是否被授權(quán)監(jiān)聽該頻道。

所有的授權(quán)回調(diào)接收當(dāng)前被認(rèn)證的用戶作為第一個參數(shù),任何額外的通配符參數(shù)作為后續(xù)參數(shù)。在本例中,我們使用 {orderId} 占位符來表示頻道名稱的 「ID」 部分是通配符。

對事件廣播進(jìn)行監(jiān)聽

接下來,就只剩下在 JavaScript 應(yīng)用程序中監(jiān)聽事件了。我們可以通過 Laravel Echo 來實(shí)現(xiàn)。首先,我們使用 private 方法來訂閱私有頻道。然后,使用 listen 方法來監(jiān)聽 ShippingStatusUpdated 事件。默認(rèn)情況下,事件的所有公有屬性會被包括在廣播事件中:

Echo.private(`order.${orderId}`)
    .listen('ShippingStatusUpdated', (e) => {
        console.log(e.update);  
      });

定義廣播事件

要告知 Laravel 一個給定的事件需要廣播,只需要在事件類中實(shí)現(xiàn) Illuminate\Contracts\Broadcasting\ShouldBroadcast 接口即可。該接口已被導(dǎo)入到所有由框架生成的事件類中,所以你可以很方便地將它添加到你自己的事件中。

ShouldBroadcast 接口要求你實(shí)現(xiàn)一個方法: broadcastOn 。 該方法返回一個頻道或者一個頻道數(shù)組,事件會被廣播到這些頻道。這些頻道必須是 ChannelPrivateChannel 或者 PresenceChannel 的實(shí)例。 Channel 代表任何用戶都可以訂閱的公開頻道, 而 PrivateChannelsPresenceChannels 則代表需要 頻道授權(quán) 的私有頻道:

<?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;  
     /**
     * 創(chuàng)建一個新的事件實(shí)例。
     *
     * @return void
     */ 
      public function __construct(User $user) 
         {      
             $this->user = $user; 
         }   
      /**
     *獲得事件廣播的頻道。
     *
     * @return Channel|array
     */   
   public function broadcastOn()  
     {     
        return new PrivateChannel('user.'.$this->user->id);   
      }
 }

然后,你只需要像你平時那樣 觸發(fā)事件 。一旦事件被觸發(fā),一個 隊(duì)列任務(wù) 會自動廣播事件到你指定的廣播驅(qū)動上。

廣播名稱

Laravel 默認(rèn)會使用事件的類名作為廣播名稱來廣播事件。不過,你也可以在事件類中定義一個 broadcastAs 方法來自定義廣播名稱:

/**
 * 事件的廣播名稱。
 *
 * @return string
 */
 public function broadcastAs(){
     return 'server.created';
  }

如果你使用了 broadcastAs 方法來自定義廣播名稱,你應(yīng)當(dāng)確保在你注冊監(jiān)聽器時加上一個 . 的前綴。這將指示 Echo 不要在事件之前添加應(yīng)用程序的命名空間:

.listen('.server.created', function (e) {
    ....
});

廣播數(shù)據(jù)

當(dāng)一個事件被廣播時,其所有的 public 屬性都會自動序列化并作為事件有效載荷進(jìn)行廣播,這允許你在 JavaScript 應(yīng)用程序中訪問到事件所有的公有數(shù)據(jù)。舉個例子,如果你的事件有一個單獨(dú)的包含了一個 Eloquent 模型的公有 $user 屬性,那么事件的廣播有效載荷將會是:

{ 
   "user": {
       "id": 1,       
       "name": "Patrick Stewart"  
      ...  
      }
 }

不過,如果你想更細(xì)粒度地控制你的廣播有效載荷,你可以向你的事件中添加一個 broadcastWith 方法。這個方法會返回一個你想要作為事件有效載荷進(jìn)行廣播的數(shù)據(jù)數(shù)組:

/**
 * 指定廣播數(shù)據(jù)。
 *
 * @return array
 */
 public function broadcastWith(){
     return ['id' => $this->user->id];
 }

廣播隊(duì)列

默認(rèn)情況下,每一個廣播事件都會被推送到在 queue.php 配置文件中指定的默認(rèn)隊(duì)列連接相應(yīng)的默認(rèn)隊(duì)列中。你可以在事件類中定義一個 broadcastQueue 屬性來自定義廣播器所使用的隊(duì)列。該屬性需要你指定廣播時你想要用的隊(duì)列名稱:

/**
 * 事件被推送到的隊(duì)列名稱。
 *
 * @var string
 */
 public $broadcastQueue = 'your-queue-name';

如果你想使用 sync 隊(duì)列而不是默認(rèn)隊(duì)列驅(qū)動來廣播事件,你可以實(shí)現(xiàn) ShouldBroadcastNow 接口而不是 ShouldBroadcast

<?php
  use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
  class ShippingStatusUpdated implements ShouldBroadcastNow{ 
     //
  }

廣播條件

有時,你想在給定條件為 true 的情況下才廣播你的事件。你可以通過在事件類中添加一個 broadcastWhen 方法來定義這些條件:

/**
 * 判定事件是否可以廣播。
 *
 * @return bool
 */
 public function broadcastWhen(){ 
    return $this->value > 100;
 }

授權(quán)頻道

對于私有頻道,用戶只有被授權(quán)之后才能監(jiān)聽。實(shí)現(xiàn)過程是用戶向你的 Laravel 應(yīng)用程序發(fā)起一個攜帶頻道名稱的 HTTP 請求,由你的應(yīng)用程序判斷該用戶是否能夠監(jiān)聽該頻道。在使用 Laravel Echo 時,授權(quán)訂閱私有頻道的 HTTP 請求會自動發(fā)送;盡管如此,你仍需定義相應(yīng)的路由來響應(yīng)這些請求。

定義授權(quán)路由

幸運(yùn)的是,在 Laravel 中我們可以很容易地定義路由來響應(yīng)頻道授權(quán)請求。在 Laravel 自帶的 BroadcastServiceProvider 中,你可以看到對 Broadcast::routes 方法的調(diào)用。該方法會注冊 /broadcasting/auth 路由來處理授權(quán)請求:

Broadcast::routes();

Broadcast::routes 方法會自動將它的路由置入 web 中間件組中;不過,如果你想自定義指定的屬性,你可以向該方法傳遞一個路由屬性數(shù)組:

Broadcast::routes($attributes);

自定義授權(quán)端點(diǎn)

默認(rèn)情況下,Echo 將使用 /broadcasting/auth 端點(diǎn)來授權(quán)頻道訪問。 但是,您可以通過將 authEndpoint 配置選項(xiàng)傳遞給 Echo 實(shí)例來指定自己的授權(quán)端點(diǎn):

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    authEndpoint: '/custom/endpoint/auth'
 });

定義授權(quán)回調(diào)

接下來,我們需要定義真正用于處理頻道授權(quán)的邏輯。該邏輯在應(yīng)用程序自帶的 routes/channels.php 文件中完成。在這個文件中,你可以使用 Broadcast::channel 方法來注冊頻道授權(quán)回調(diào):

Broadcast::channel('order.{orderId}', function ($user, $orderId) { 
   return $user->id === Order::findOrNew($orderId)->user_id;
});

channel 方法接收兩個參數(shù):頻道名稱和一個回調(diào)函數(shù),該回調(diào)通過返回 true 或者 false 來表示用戶是否被授權(quán)監(jiān)聽該頻道。

所有的授權(quán)回調(diào)接收當(dāng)前認(rèn)證用戶作為第一個參數(shù),任何額外的通配符參數(shù)作為后續(xù)參數(shù)。在本例中,我們使用 {orderId} 占位符來表示頻道名稱的 「ID」 部分是通配符。

授權(quán)回調(diào)模型綁定

就像 HTTP 路由一樣,頻道路由也可以利用顯式或隱式 路由模型綁定 。例如,你可以請求接收一個真正的 Order 模型實(shí)例,而不是字符串或數(shù)字類型的 order ID:

use App\Order;
Broadcast::channel('order.{order}', function ($user, Order $order) { 
   return $user->id === $order->user_id;
 });

授權(quán)回調(diào)驗(yàn)證

私有頻道和在線廣播頻道通過應(yīng)用程序的默認(rèn)授權(quán)驗(yàn)證對當(dāng)前用戶身份進(jìn)行驗(yàn)證。 如果用戶未經(jīng)過授權(quán)驗(yàn)證,則會自動拒絕通道授權(quán),并且永遠(yuǎn)不會執(zhí)行授權(quán)回調(diào)。 但是,您可以分配多個自定義防護(hù),以便在必要時對傳入請求進(jìn)行身份驗(yàn)證:

 Broadcast::channel('channel', function() { 
    // ...
  }, ['guards' => ['web', 'admin']])

定義頻道類

如果你的應(yīng)用程序用到了許多不同的頻道,你的 routes/channels.php 文件可能會變得很龐大。所以,你可以使用頻道類來代替使用閉包授權(quán)頻道。要生成一個頻道類,請使用 make:channel Artisan 命令。該命令會在 App/Broadcasting 目錄中放置一個新的頻道類。

php artisan make:channel OrderChannel

接下來,在你的 routes/channels.php 文件中注冊你的頻道:

use App\Broadcasting\OrderChannel;
Broadcast::channel('order.{order}', OrderChannel::class);

最后,你可以將頻道的授權(quán)邏輯放入頻道類的 join 方法中。該 join 方法將保存你通常放置在頻道授權(quán)閉包中的相同邏輯。當(dāng)然,你也可以利用頻道模型綁定:

<?php
    namespace App\Broadcasting;
    use App\User;use App\Order;
    class OrderChannel{   
     /**
     * 創(chuàng)建一個新的頻道實(shí)例。
     *
     * @return void
     */ 
     public function __construct()  
       {     
          //  
        }   
     /**
     * 認(rèn)證用戶的頻道訪問權(quán)限。
     *
     * @param  \App\User  $user
     * @param  \App\Order  $order
     * @return array|bool
     */    
    public function join(User $user, Order $order) 
       {     
          return $user->id === $order->user_id;  
        }
   }

{注} 就像 Laravel 中的很多其它類,頻道類會通過 服務(wù)容器 自動解析。因此,你可以在頻道類的構(gòu)造函數(shù)中對其進(jìn)行所需依賴項(xiàng)的類型提示。

廣播事件

定義好一個事件且將其標(biāo)記實(shí)現(xiàn) ShouldBroadcast 接口之后,你所要做的僅僅是通過 event 函數(shù)來觸發(fā)該事件。事件分發(fā)器會識別出標(biāo)記了實(shí)現(xiàn) ShouldBroadcast 接口的事件,并將其推送到隊(duì)列中進(jìn)行廣播:

event(new ShippingStatusUpdated($update));

只廣播給他人

當(dāng)創(chuàng)建一個會用到事件廣播的應(yīng)用程序時,你可以使用 broadcast 函數(shù)來代替 event 。和 event 函數(shù)一樣, broadcast 函數(shù)將事件分發(fā)到服務(wù)端監(jiān)聽器:

broadcast(new ShippingStatusUpdated($update));

不過, broadcast 函數(shù)還有一個允許你將當(dāng)前用戶排除在廣播接收者之外的 toOthers 方法:

broadcast(new ShippingStatusUpdated($update))->toOthers();

為了更好地理解什么時候使用 toOthers 方法,讓我們假設(shè)有一個任務(wù)列表的應(yīng)用程序,用戶可以通過輸入任務(wù)名來新建任務(wù)。要新建任務(wù),你的應(yīng)用程序需要發(fā)起一個請求到一個 /task 路由,該路由會廣播任務(wù)的創(chuàng)建,并返回新任務(wù)的 JSON 響應(yīng)。當(dāng)你的 JavaScript 應(yīng)用程序從路由收到響應(yīng)后,它會直接將新任務(wù)插入到任務(wù)列表中,就像這樣:

axios.post('/task', task) 
   .then((response) => {
        this.tasks.push(respo   
      });

然而,別忘了,我們還廣播了任務(wù)的創(chuàng)建。如果你的 JavaScript 應(yīng)用程序正在監(jiān)聽該事件以便添加任務(wù)至任務(wù)列表,任務(wù)列表中將出現(xiàn)重復(fù)的任務(wù):一個來自路由響應(yīng),另一個來自廣播。你可以通過使用 toOthers 方法告知廣播器不要將事件廣播到當(dāng)前用戶來解決這個問題。

{注} 為了能調(diào)用 toOthers 方法,你的事件必須使用 Illuminate\Broadcasting\InteractsWithSockets trait 。

配置

當(dāng)你初始化 Laravel Echo 實(shí)例的時候,一個套接字 ID 會被分配到該連接。如果你使用了 VueAxios ,該套接字 ID 會自動地以 X-Socket-ID 頭的方式添加到每一個傳出請求中。那么,當(dāng)你調(diào)用 toOthers 方法時,Laravel 會從請求頭中取出套接字 ID ,并告知廣播器不要廣播任何消息到帶有這個套接字 ID 的連接上。

你如果你沒有使用 Vue 和 Axios ,則需要手動配置 JavaScript 應(yīng)用程序來發(fā)送 X-Socket-ID 請求頭。你可以用 Echo.socketId 方法來獲取套接字 ID :

var socketId = Echo.socketId();

接收廣播

安裝 Laravel Echo

Laravel Echo 是一個 JavaScript 庫,有了這個庫之后,訂閱頻道監(jiān)聽 Laravel 廣播的事件變得非常容易。你可以通過 NPM 包管理器來安裝 Echo 。在本例中,因?yàn)槲覀儠褂?Pusher 廣播器,所以我們也會安裝 pusher-js 包:

npm install --save laravel-echo pusher-js

安裝好 Echo 之后,你就可以在應(yīng)用程序的 JavaScript 中創(chuàng)建一個全新的 Echo 實(shí)例。做這件事的一個理想的地方是在 Laravel 框架自帶的 resources/js/bootstrap.js 文件的底部:

import Echo from "laravel-echo"
window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key'
  });

當(dāng)你使用 pusher 連接器來創(chuàng)建一個 Echo 實(shí)例的時候,還可以指定 cluster 以及連接是否需要加密:

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    cluster: 'eu',
    encrypted: true
 });

使用現(xiàn)有客戶端實(shí)例

如果您已經(jīng)有一個希望 Echo 使用的 Pusher 或 Socket.io 客戶端實(shí)例,您可以通過 client 配置選項(xiàng)將其傳遞給 Echo:

const client = require('pusher-js');
window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    client: client
 });

對事件進(jìn)行監(jiān)聽

安裝并實(shí)例化 Echo 之后, 你就可以開始監(jiān)聽事件廣播了。首先,使用 channel 方法獲取一個頻道實(shí)例,然后調(diào)用 listen 方法來監(jiān)聽指定的事件:

Echo.channel('orders') 
   .listen('OrderShipped', (e) => {
        console.log(e.order.name);  
   });

如果你想監(jiān)聽私有頻道上的事件,請使用 private 方法。你可以通過鏈?zhǔn)秸{(diào)用 listen 方法來監(jiān)聽單個頻道上的多個事件:

Echo.private('orders') 
   .listen(...)    
   .listen(...)    
   .listen(...);

退出頻道

要離開頻道,您可以在 Echo 實(shí)例上調(diào)用 leaveChannel 方法:

Echo.leaveChannel('orders');

如果您想離開私有頻道和在線頻道,您可以調(diào)用 leave 方法:

Echo.leave('orders');

命名空間

你可能已經(jīng)注意到在上面的例子中,我們并沒有為事件類指定完整的命名空間。這是因?yàn)?Echo 會默認(rèn)事件都在 App\Events 命名空間下。不過,你可以在實(shí)例化 Echo 時傳遞一個 namespace 配置項(xiàng)來指定根命名空間:

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',    
    namespace: 'App.Other.Namespace'
 });

另外,你可以在使用 Echo 訂閱事件的時候?yàn)槭录惣由?. 前綴。這樣就可以指定完全限定名稱的類名了:

Echo.channel('orders') 
   .listen('.Namespace.Event.Class', (e) => {     
      //  
    });

Presence 頻道

Presence 頻道構(gòu)建在私有頻道的安全性基礎(chǔ)之上,并提供了額外的特性:獲知誰訂閱了該頻道。這一點(diǎn)使構(gòu)建強(qiáng)大的,協(xié)同的應(yīng)用變得非常容易,比如一個用戶在瀏覽頁面時,通知其他正在瀏覽相同頁面的用戶。

授權(quán) Presence 頻道

所有的 presence 頻道也是私有頻道;因此,用戶必須被 授權(quán)之后才能訪問 。不過,在給 presence 頻道定義授權(quán)回調(diào)函數(shù)時,如果一個用戶已經(jīng)加入了該頻道,那么不應(yīng)該返回 true ,而應(yīng)該返回一個關(guān)于該用戶信息的數(shù)組。

由授權(quán)回調(diào)函數(shù)返回的數(shù)據(jù)能夠在你的 JavaScript 應(yīng)用程序中被 presence 頻道事件監(jiān)聽器所使用。如果用戶沒有被授權(quán)加入該 presence 頻道,那么你應(yīng)該返回 false 或者 null

Broadcast::channel('chat.{roomId}', function ($user, $roomId) { 
   if ($user->canJoinRoom($roomId)) {      
     return ['id' => $user->id, 'name' => $user->name];  
     }
   });

加入 Presence 頻道

你可以使用 Echo 的 join 方法來加入 presence 頻道。 join 方法會返回一個實(shí)現(xiàn)了 PresenceChannel 的對象,通過暴露 listen 方法,允許你訂閱 here 、 joiningleaving 事件。

Echo.join(`chat.${roomId}`) 
   .here((users) => {    
       //  
     })    
   .joining((user) => {
        console.log(user.name);   
        }) 
    .leaving((user) => {
        console.log(user.name); 
       });

here 回調(diào)函數(shù)會在你成功加入頻道后被立即執(zhí)行,并接收一個包含其他所有當(dāng)前訂閱該頻道的用戶的用戶信息數(shù)組 。 joining 方法會在新用戶加入頻道時被執(zhí)行,而 leaving 方法會在用戶退出頻道時被執(zhí)行。

廣播到 Presence 頻道

Presence 頻道可以像公開和私有頻道一樣接收事件。使用一個聊天室的例子,我們可能想把 NewMessage 事件廣播到聊天室的 presence 頻道。要實(shí)現(xiàn)它,我們將從事件的 broadcastOn 方法中返回一個 PresenceChannel 實(shí)例:

/**
 * 獲得事件廣播的頻道。
 *
 * @return Channel|array
 */
 public function broadcastOn(){
     return new PresenceChannel('room.'.$this->message->room_id);
   }

就像公開或私有事件, presence 頻道事件也可以使用 broadcast 函數(shù)來廣播。同樣的,你也可以使用 toOthers 方法將當(dāng)前用戶排除在廣播接收者之外:

broadcast(new NewMessage($message));
broadcast(new NewMessage($message))->toOthers();

你可以通過 Echo 的 listen 方法來監(jiān)聽 join 事件:

Echo.join(`chat.${roomId}`) 
   .here(...)    
   .joining(...)    
   .leaving(...)    
   .listen('NewMessage', (e) => {  
         //   
     });

客戶端事件

{注} 使用 Pusher 時,如果要發(fā)送客戶端事件,你必須在 應(yīng)用后臺 的「應(yīng)用設(shè)置」部分啟用「客戶端事件」選項(xiàng)。

有時,你可能希望廣播一個事件給其它已經(jīng)連接的客戶端,但不通知你的 Laravel 應(yīng)用程序。這在處理「輸入中」這類事情的通知時尤其有用,比如提醒你應(yīng)用的用戶,另一個用戶正在給定屏幕上輸入信息。

你可以使用 Echo 的 whisper 方法來廣播客戶端事件:

Echo.private('chat') 
   .whisper('typing', {
        name: this.user.name    
    });

你可以使用 listenForWhisper 方法來監(jiān)聽客戶端事件:

Echo.private('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name); 
     });

消息通知

通過與將事件廣播與 消息通知 配對,你的 JavaScript 應(yīng)用程序可以在不刷新頁面的情況下接收新的消息通知。在此之前,請確保你已經(jīng)讀過了如何使用 廣播通知頻道 的文檔。

配置好使用廣播頻道的消息通知后,你可以使用 Echo 的 notification 方法來監(jiān)聽廣播事件。謹(jǐn)記,頻道名稱應(yīng)該和接收消息通知的實(shí)體類名相匹配:

Echo.private(`App.User.${userId}`) 
   .notification((notification) => {
        console.log(notification.type); 
      });

在本例中,所有通過 broadcast 頻道發(fā)送到 App\User 實(shí)例的消息通知都會被回調(diào)接收。一個針對 App.User.{id} 頻道的授權(quán)回調(diào)函數(shù)已經(jīng)包含在 Laravel 框架內(nèi)置的 BroadcastServiceProvider 中了。

本文章首發(fā)在 LearnKu.com 網(wǎng)站上。