laravel7.0廣播機(jī)制(Redis + socket.io)
廣播服務(wù)提供者
在廣播任意事件之前,首先需要注冊(cè)AppProvidersBroadcastServiceProvider
。在新安裝的 Laravel 應(yīng)用中,你只需要取消 config/app.php
配置文件中 providers
數(shù)組內(nèi)對(duì)應(yīng)服務(wù)提供者之前的注釋即可。該提供者允許你注冊(cè)廣播授權(quán)路由和回調(diào)
相關(guān)欄目教程推薦:《laravel教程》
設(shè)置 Redis 連接
需要修改 .env
文件中的廣播驅(qū)動(dòng)為 redis
:
BROADCAST_DRIVER=redis
建立 Event
php artisan make:event OrderShipped
執(zhí)行上訴命令之后 app 目錄下會(huì)出現(xiàn)一個(gè) Events 目錄,在該目錄下產(chǎn)生了廣播事件類 OrderShipped.php
。我們要對(duì)自動(dòng)生成的 OrderShipped 類進(jìn)行以下修改
-
增加對(duì) ShouldBroadcast 的實(shí)現(xiàn)
-
修改 broadcastOn 方法,使用公共廣播通道 orderStatus
-
自定義廣播的消息名(非必須)【默認(rèn)情況下,Laravel 會(huì)使用事件的類名來(lái)廣播事件,不過(guò),你可以通過(guò)在事件中定義 broadcastAs 方法來(lái)自定義廣播名稱:】
-
修改構(gòu)造函數(shù)
完整修改如下 可直接替換
<?php namespace AppEvents; use IlluminateBroadcastingChannel; use IlluminateBroadcastingInteractsWithSockets; use IlluminateBroadcastingPresenceChannel; use IlluminateBroadcastingPrivateChannel; use IlluminateContractsBroadcastingShouldBroadcast; use IlluminateFoundationEventsDispatchable; use IlluminateQueueSerializesModels; class OrderShipped implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; //可添加任意成員變量 public $id; //事件構(gòu)造函數(shù) public function __construct($id) { $this->id = $id; } //自定義廣播的消息名 public function broadcastAs() { return 'anyName'; } /** * Get the channels the event should broadcast on. * * @return IlluminateBroadcastingChannel|array */ public function broadcastOn() { return new Channel('orderStatus'); } }
設(shè)置 api 路由
Route::get('/ship', function (Request $request) { $id = $request->input('id'); broadcast(new OrderShipped($id)); // 觸發(fā)事件 return 'Order Shipped!'; });
安裝前端腳手架
composer require laravel/uiphp artisan ui vue --auth
Redis
因?yàn)樵蹅兪褂?Redis 廣播,需要安裝 Predis 庫(kù):
composer require predis/predis
Redis 廣播使用 Redis 的 pub/sub 功能進(jìn)行廣播;不過(guò),你需要將其和能夠接受 Redis 消息的 Websocket 服務(wù)器進(jìn)行配對(duì)以便將消息廣播到 Websocket 頻道
當(dāng) Redis 廣播發(fā)布事件時(shí),事件將會(huì)被發(fā)布到指定的頻道上,傳遞的數(shù)據(jù)是一個(gè) JSON 格式的字符串,其中包含了事件名稱、負(fù)載數(shù)據(jù) data、以及生成事件 socket ID 的用戶
安裝 laravel-echo-server 訂閱 Redis Sub
如果使用 pusher 那么直接使只用 laravel 就可以了,如果使用 Redis + socket.io 則需要使用開源項(xiàng)目 laravel-echo-server 。所以我們現(xiàn)在要使用 laravel-echo-server
全局安裝
npm install -g laravel-echo-server
初始化 laravel-echo-server
laravel-echo-server init // 是否在開發(fā)模式下運(yùn)行此服務(wù)器(y/n) 輸入y ? Do you want to run this server in development mode? (y/N)// 設(shè)置服務(wù)器的端口 默認(rèn) 6001 輸入 6001就可以了 或者你想要的 ? Which port would you like to serve from? (6001)// 想用的數(shù)據(jù)庫(kù) 選擇 redis ? Which database would you like to use to store presence channel members? (Use arrow keys)? redis sqlite // 這里輸入 你的laravel 項(xiàng)目的訪問(wèn)域名 ? Enter the host of your Laravel authentication server. (http://localhost)// 選擇 網(wǎng)絡(luò)協(xié)議 http ? Will you be serving on http or https? (Use arrow keys)? http https // 您想為HTTP API生成客戶端ID/密鑰嗎 N ? Do you want to generate a client ID/Key for HTTP API? (y/N)// 要設(shè)置對(duì)API的跨域訪問(wèn)嗎?(y/n)N Configuration file saved. Run laravel-echo-server start to run server. //您希望將此配置另存為什么? (laravel-echo-server.json)回車就行 ? What do you want this config to be saved as? (laravel-echo-server.json)
啟動(dòng) laravel-echo-server
laravel-echo-server start
- 成功啟動(dòng)后會(huì)輸出以下日志
L A R A V E L E C H O S E R V E R version 1.6.0 ⚠ Starting server in DEV mode... ✔ Running at localhost on port 6001 ✔ Channels are ready. ✔ Listening for http events... ✔ Listening for redis events... Server ready!
測(cè)試廣播
在瀏覽器上執(zhí)行 http://yourhost/api/ship?id=16
Channel: laravel_database_orderStatus Event: anyName
- laravel-echo-server 連接成功!
安裝 laravel-echo 的前依賴
由于前端使用的是 laravel-echo
來(lái)收聽(tīng)廣播,我們選擇的底層實(shí)現(xiàn)方式是socket.io
。所以首先我們要在package.json
中添加 laravel-echo
和 socket.io
的依賴
npm i --save socket.io-client npm i --save laravel-echo
編輯 resource/js/bootstrap.js 添加如下代碼
import Echo from "laravel-echo"; window.io = require("socket.io-client"); window.Echo = new Echo({ broadcaster: "socket.io", host: window.location.hostname + ":6001" });
測(cè)試頁(yè)面
在 resources/views/
下建立頁(yè)面 test.blade.php 內(nèi)容為
<!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=""> <title>News Room</title> <link href="" rel="stylesheet"> </head> <body> <div class="content"> News Room </div> <script src=""></script> <script> Echo.channel("laravel_database_orderStatus") // 廣播頻道名稱 .listen(".anyName", e => { // 消息名稱 console.log(e); // 收到消息進(jìn)行的操作,參數(shù) e 為所攜帶的數(shù)據(jù) }); </script> </body> </html>
js 代碼的意思是收聽(tīng) news 通道內(nèi)的 News 事件對(duì)象,將接收到的事件在控制臺(tái)打印出來(lái)。
基本構(gòu)建
npm install && npm run watch