藉助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