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

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

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

php artisan --version
若是低於 5.4 請從新創建新版本的Laravel,具體方法在下面會詳細講解。html

 

實例背景:
假設場景:
假設咱們要使用laravel做爲服務端作一個新聞推送系統。用戶打開頁面後不須要刷新頁面便可不斷的獲取到最新的新聞。前端

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

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

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

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訂閱服務的訂閱者。
這幾樣東西配合起來的架構圖以下redis

 

根據這幅圖咱們能夠知道事件的廣播機制流程:npm

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對象
廣播事件種類:json

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

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


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

二、安裝redis(不改動的狀況下安裝好後redis使用默認便可)

   

composer required predis/predis

三、配置.env文件

  

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

BROADCAST_DRIVER=redis

設置queue爲redis

QUEUE_DRIVER=redis

四、創建事件(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'); } }

五、增長廣播路由(routes\channels.php)

 

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

六、測試廣播:

   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 重載生效

 

九、瀏覽器收聽廣播

       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

相關文章
相關標籤/搜索