laravel 5.5 廣播(broadcast)的配置及使用


借助Laravel Broadcasting你可以使用上時下很熱的Websocket技術。

注意:請務必使用較新版本的 Laravel。Laravel在最近幾個版本進行過比較大的重構,比如路由從 app\Http\routes.php 拆分為到 routes 目錄下的多個文件,包括廣播在內的各個附加組件也都進行了重構並正式寫入文檔。所以網上有些教程(特別是入門教程)可能是根據舊版本來寫的,容易讓你迷惑。當安裝完Laravel后執行以下命令查看Laravel版本

php artisan --version
如果低於 5.4 請重新建立新版本的Laravel,具體方法在下面會詳細講解。

 

實例背景:
假設場景:
假設我們要使用laravel作為服務端做一個新聞推送系統。用戶打開頁面后不需要刷新頁面即可不斷的獲取到最新的新聞。

環境參數
Homestead 7.4.2
Laravel 5.5 (廣播機制在 5.4 以后進行了一次重構,並正式加入文檔,所以請務必使用 5.4 及其以上版本)
PHP 7.1
Redis 4.0.9 (Homestead 自帶redis)
————————————————

廣播架構
目前有兩種廣播機制可選:

pusher:laravel自帶方案,但是有使用限制,需要收費
Redis + socket.io:無限制
我們使用業界較流行的Redis + socket.io 方案 。
接下來你會信息爆炸似的接收到好幾個新名詞:

laravel-echo-server:使用 socket.io 機制實現的 broadcasting 服務端
laravel-echo:laravel-echo是 laravel broadcasting 的客戶端。注意,laravel-echo 並不是 laravel-echo-server 專屬的客戶端, laravel-echo 有兩種連接機制可以選:pusher 和 socket.io 。 而 laravel-echo-server 是開發出來專門用於 socket.io連接的服務端。如果你使用的是 pusher,那么不需要使用 laravel-echo-server ,但是你依然要使用 laravel-echo
Socket.IO:websocket 的一種nodejs實現。laravel-echo 如果要使用socket.io 則需要先安裝 socket.io-client。
Predis:redis客戶端的php實現,如果要使用redis作為廣播機制的實現,則需要先安裝 predis
Laravel Event:廣播事件類
Laravel Queue:廣播機制是基於queue機制來實現的
Redis Sub/Pub:Redis的訂閱機制。laravel-echo-server本質上只是一個Redis訂閱服務的訂閱者。
這幾樣東西配合起來的架構圖如下

 

根據這幅圖我們可以知道事件的廣播機制流程:

Laravel 通過 broadcasting 機制發布一個Event對象到Redis
Laravel Queue Worker 讀取該Event對象,並使用Redis的Sub/Pub機制將該 Event對象發布出去
laravel-echo-server  通過 Redis 的 Sub/Pub機制收聽到該 Event
由於 laravel-echo 使用 socket.io 跟 laravel-echo-server相連接。所以 laravel-echo 會通過socket.io將Event對象發送給laravel-echo
laravel-echo解析通過 socket.io接收到的 Event對象
廣播事件種類:

public:誰都可以收聽的廣播
private:只有指定用戶可以收到的廣播
presence:不僅可以收聽到跟你有關的廣播,還可以跟別的用戶互動,適合做聊天室
我們假設的場景是新聞推送系統,所以使用最簡單的public廣播就可以實現。接下來我們詳細的來講解如何將這些組件配置好,並連接起來。

我們按照廣播機制的流程來一步一步的設置廣播機制。


1、注冊 BroadcastServiceProvider,打開 config/app.php 找到 'provides' 屬性,將 BroadcastServiceProvider 前的注釋去掉

2、安裝redis(不改動的情況下安裝好后redis使用默認即可)

   

composer required predis/predis

3、配置.env文件

  

由於廣播機制是基於queue機制實現的。所以queue的存儲設置會直接決定廣播事件的存儲位置

BROADCAST_DRIVER=redis

設置queue為redis

QUEUE_DRIVER=redis

4、建立事件(event)

php artisan  make:event loginLogEvent

修改事件源碼增加廣播頻道:

/*增加對 ShouldBroadcast 的實現*/

class loginLogEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
 
    public $message;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($news_message)
    {
        $this->message = $news_message;
    }
 
    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('loginLogEvent');
    }
}

5、增加廣播路由(routes\channels.php)

 

/*channel 方法接收兩個參數:頻道名稱和一個回調函數,該回調通過返回 true 或者 false 來表示用戶是否被授權監聽該頻道*/
Broadcast::channel('loginLogEvent',function ($user,$id)
{
    return true;
});

6、測試廣播:

   1)編輯 routes/console.php ,增加 bignews 命令:

        

/*自定義命令*/
Artisan::command('bignews', function () {
    broadcast(new loginLogEvent(date('Y-m-d h:i:s A').": BIG NEWS!"));
    $this->comment("news sent");})->describe('Send news');

  2)測試命令:

       輸入:php artisan bignews

     

   通過 redis-cli 查看當前redis中的數據,發現多出來一個queue對象,證明連接成功了,如果沒有,請檢查env配置中的queue配置是否正確

   你還你可以在queue worker的執行界面看到該Event已經被檢測到,並通過Redis Sub/Pub機制傳播出去了

   

7:安裝並配置 laravel-echo-server

 1)安裝

 
npm install -g laravel-echo-server

2)初始化 Socket 服務(切記在生產環境中,無論你什么時候使用它,都應該關掉你的開發者模式)

laravel-echo-server init

  

      它會幫你在項目根目錄下生成 laravel-echo-server.json 

3)啟動laravel-echo-server 

   

啟動/停止

laravel-echo-server start/stop

啟動后,在新打開一個終端窗口,輸入 php artisan bignews 顯示如下證明廣播推送到了laravel-echo-server

 8:端口映射:

    因為laravel-echo-server使用的是 6001 端口,所以記得去 Homestead.yaml里面添加6001 端口的映射

   

  使用命令:vagrant reload 重載生效

 

9、瀏覽器收聽廣播

       1)安裝組件
          

    

/*由於前端使用的是 laravel-echo來收聽廣播,我們選擇的底層實現方式是socket.io。所以首先我們要在package.json中添加 laravel-echo 和 socket.io的依賴*/



npm i --save laravel-echo


npm i --save socket.io-client

  

      2)配置/resources/assets/js/bootstrap.js        

    

import Echo from 'laravel-echo'
/*使用 pusher
window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    cluster: 'mt1',
    encrypted: true
 });
*/
/*使用 socket.io-client*/
window.io = require('socket.io-client');

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host:window.location.hostname+':6001'
});

  

 

  3) 重新編譯app.js 文件

 

   

    注意:*默認使用 http://registry.npmjs.org在國內不穩定,如果出現404錯誤,可切換使用國內鏡像*

  npm config set registry= https://registry.npm.taobao.org

npm run dev

  

       4) 建立測試文件

            在resources\views\目錄下新建boradcast.blade.php 文件,放入以下內容

            

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>News Room</title>
    <link href="{{ mix('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div class="content">
    News Room
</div>
<script src="{{ mix('js/app.js') }}"></script>
<script>
    /*收聽loginLogEvent通道內的loginLogEvent事件對象,將接收到的事件在控制台打印出來。*/
   Echo.channel('loginLogEvent')
        .listen('loginLogEvent', (e) => {
            alert(JSON.stringify(e));
            console.log(e.message);
        });
</script>
</body>

 5)在rotues/web.php 加入路由路徑

         

Route::view('broadcast','boradcast');

 6)查看效果 

     啟動步驟:打開一個命令窗口啟動 :    laravel-echo-server start

      再打開一個窗口啟動隊列啟動隊列: php artisan queue:work 

      給隊列加內容: php artisan bignews

  

         

 

    參考:https://blog.csdn.net/nsrainbow/article/details/80428769

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM