先附上 github地址
github.com/wanghao-fan/laravel-ech...
本 文中 僅使用了 redis的廣播驅動
思路
laravel 的廣播系統和佇列系統類似,需要兩個程式協作,一個是 laravel 的 web 後臺系統,另一個是 Socket.IO 伺服器系統。具體的流程是頁面載入時,網頁 js 程式 Laravel Echo 與 Socket.IO 伺服器建立連線, laravel 發起透過驅動釋出廣播,Socket.IO 伺服器接受廣播內容,對連線的客戶端網頁推送資訊,以達到網頁實時更新的目的。
配置
配置檔案 config/broadcasting.php,可以直接在 .env 中配置以下程式碼
BROADCAST_DRIVER=redis
廣播服務提供者
config/app.php 配置檔案中 providers陣列中開啟註釋
App\Providers\BroadcastServiceProvider::class,
CSRF令牌
Laravel Echo需要訪問當前 Session 的 CSRF 令牌(token)
自建立的 blade檢視的 head中 加入 meta標籤
<meta name="csrf-token" content="{{ csrf_token() }}">
Redis
Redis廣播需要安裝 Predis庫
composer require predis/predis
安裝Laravel Echo
Laravel Echo是一個JavaScript庫,web端可以輕鬆訂閱頻道並收聽Laravel廣播的事件
透過 npm 包管理器安裝 Echo
npm install
npm install -g laravel-echo-server
初始化 laravel-echo-server
laravel-echo-server init
// 是否在開發模式下執行此伺服器(y/n) 輸入y
? Do you want to run this server in development mode? (y/N)
// 設定伺服器的埠 預設 6001 輸入 6001就可以了 或者你想要的
? Which port would you like to serve from? (6001)
// 想用的資料庫 選擇 redis
? Which database would you like to use to store presence channel members? (Use arrow keys)
❯ redis
sqlite
// 這裡輸入 你的laravel 專案的訪問域名
? Enter the host of your Laravel authentication server. (http://localhost)
// 選擇 網路協議 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)
// 要設定對API的跨域訪問嗎?(y/n)N
Configuration file saved. Run laravel-echo-server start to run server.
設定完成後 專案根目錄 下 會生成 laravel-echo-server.json 檔案 這裡面就是剛才的配置
執行命令啟動 服務 出現如下 則啟動成功
laravel-echo-server start
L A R A V E L E C H O S E R V E R
version 1.4.2
⚠ Starting server in DEV mode...
✔ Running at localhost on port 6001
✔ Channels are ready.
✔ Listening for http events...
✔ Listening for redis events...
Server ready!
頻道
頻道必須是 Channel、PrivateChannel 或 PresenceChannel 的例項。Channel 例項表示任何使用者都可以訂閱的公開頻道,而 PrivateChannels 和 PresenceChannels 則表示需要 頻道授權 的私有頻道:
建立事件
php artisan make:event PublicMessageEvent
檔案生成目錄 app/Events
// 訊息內容
public $message;
public function __construct(string $message)
{
$this->message = $message;
}
// 返回一個公共頻道 頻道名稱為push
public function broadcastOn()
{
return new Channel('push');
}
// Laravel 預設會使用事件的類名作為廣播名稱來廣播事件,自定義:
public function broadcastAs()
{
return 'push.message';
}
新增路由
use App\Events\PublicMessageEvent;
Route::get('/echo', function () {
return view('echo');
});
Route::get('/push/{message}', function ($message) {
broadcast(new PublicMessageEvent($message));
})
前端
安裝 laravel-echo
npm install laravel-echo
編輯 resource/js/bootstrap.js 新增如下程式碼
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
編輯 resource/js/app.js 新增如下程式碼
Echo.channel('push')
.listen('.push.message', (e) => {
alert('來了')
console.log(e);
});
建立 echo.blade.php
head 中加上
<meta name="csrf-token" content="{{ csrf_token() }}">
<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>
<script src="/js/app.js"></script>
編譯 js 檔案
npm run watch
瀏覽器訪問 專案域名/echo
瀏覽器訪問 專案域名/push/這是一個測試廣播
echo 頁面 會自動彈出
到這 廣播 釋出到公共頻道就完成了
私有頻道 PrivateChannel
建立事件
php artisan make:event PrivateMessageEvent
PrivateMessageEvent 中 寫入 以下內容
class PrivateMessageEvent implements ShouldBroadcast
{
// 訊息內容
public $message;
// 使用者
public $user;
public function __construct(User $user, string $message)
{
$this->user = $user;
$this->message = $message;
}
// 建立私有頻道
public function broadcastOn()
{
return new PrivateChannel('privatePush.' . $this->user->id);
}
// //Laravel 預設會使用事件的類名作為廣播名稱來廣播事件,自定義:
// public function broadcastAs()
// {
// return 'privatePush.message';
// }
// 控制廣播資料:
public function broadcastWith()
{
return ['message' => $this->message,'status' => 'okok'];
}
}
新增發布廣播到私有頻道 觸發路由 routes/web
Route::get('/privatePush/{message}/{id}', function ($message, $id) {
$user = \App\User::find($id);
if (empty($user)) return '無此使用者';
broadcast(new PrivateMessageEvent($user, $message));
});
頻道授權
定義授權路由 routes/channel 中加入一下程式碼
Broadcast::channel('privatePush.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
前端
echo.blade.php 中加入
<script>
@if(!empty(Auth::user()))
window.id = "{{Auth::user()->id}}"
@endif
</script>
app.js
Echo.private('privatePush.' + window.id)
.listen('PrivateMessageEvent', (e) => {
alert('qweqwe')
console.log(e);
});
本作品採用《CC 協議》,轉載必須註明作者和本文連結