本教程會詳細介紹配置的方法,以給全體用戶發送通知為例。
1. 廣播配置說明
1.1 廣播驅動配置
文件位置 config/broadcasting.php
<?php
return [
'default' => env('BROADCAST_DRIVER', 'null'),
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
//
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];
可以看到Laravel自帶了4個廣播驅動器 pusher, redis, log, null
1.2 注冊服務提供器
服務提供器位置:App\Providers\BroadcastServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;
class BroadcastServiceProvider extends ServiceProvider
{
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
}
你只需在 config/app.php 配置文件的 providers 數組中取消對該提供者的注釋即可
2. 驅動器配置
這里采用 redis + soocket.io 的組合
2.1 安裝predis
如果你使用 Redis 廣播器,請安裝 Predis 庫:
composer require predis/predis "~1.0"
2.2. 配置服務端
這里采用社區驅動維護的項目 tlaverdure/laravel-echo-server,這是一個使用socket.io來支持laravel廣播的nodejs服務器。當運行后會將socket.io客戶端js代碼暴露在一個標准的的url中。我們需要在我們的項目中(視圖文件)引入這個地址。
2.2.1 安裝方法
npm install -g laravel-echo-server # 這里是全局安裝
2.2.2 初始化服務端
我是這樣選擇初始化配置的。可以根據自己情況改變
$ laravel-echo-server init
? Do you want to run this server in development mode? Yes
? Which port would you like to serve from? 6001
? Which database would you like to use to store presence channel members? redis
? Enter the host of your Laravel authentication server. archerwong.cn
? Will you be serving on http or https? http
? Do you want to generate a client ID/Key for HTTP API? Yes
? Do you want to setup cross domain access to the API? No
appId: c953434932b06864
key: 551440289d2d41c81e87d55c1d0217e5
Configuration file saved. Run laravel-echo-server start to run server.
2.2.3 運行服務端
$ laravel-echo-server start
L A R A V E L E C H O S E R V E R
version 1.3.6
⚠ Starting server in DEV mode...
✔ Running at localhost on port 6001
✔ Channels are ready.
✔ Listening for http events...
✔ Listening for redis events...
Server ready!
檢測下socket.io客戶端url地址是否可訪問
http://your_host_address:6001/socket.io/socket.io.js
可訪問,並內容類似於以下則說明服務器可用
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(......
2.3 配置客戶端
2.3.1 安裝laravel-echo
Laravel Echo 是一個 JavaScript 庫,它使得訂閱頻道和監聽由 Laravel 廣播的事件變得非常容易。
npm install laravel-echo --save # 安裝laravel-echo 並記錄package.json
2.3.2 創建一個全新的 Echo 實例
官方說法是在resources/assets/js/bootstrap.js文件底部引入是個好地方,打開該文件加入下面內容
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
其實如果使用blade模板,沒有使用vue等前端,我們需要在入口視圖定義id="app"掛載點,否則打包后會發現#app未定義,並且會打包進去vue等我們不需要的內容,文件也會變大,
簡單粗暴一點可以修改resource/assets/js/app.js,直接打包我們需要的內容
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
2.3.3 使用laravel-mix打包
修改 webpack.mix.js
let mix = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js');
// .sass('resources/assets/sass/app.scss', 'public/css');
生成
npm run dev
這樣我們就得到了一個壓縮的public/app.js文件
2.3.4 在視圖引入各項
- 引入csrf
Laravel Echo 會需要訪問當前會話的 CSRF 令牌,可以在應用程序的 head HTML 元素中定義一個 meta 標簽:
<meta name="csrf-token" content="{{ csrf_token() }}">
- 引入Socket.IO JavaScript 客戶端庫
<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>
- 實例化Echo
<script src="/js/app.js"></script>
<script>
<!--上面app.js已經進行了Echo的實例化,然后應該使用實例化的Echo進行廣播事件的監聽-->
console.log(Echo);
</script>
到此為止,我們基本的配置已經完成,Echo的前端監聽等后面講到再補充。
3. 后端事件
3.1 前提是配置和運行隊列偵聽器
修改.env 中的配置
QUEUE_DRIVER=redis
運行隊列監聽
php artisan queue:work
3.2 編寫事件
創建文件 app/Events/TestBroadcastingEvent.php, 內容如下
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\Http\Model\Notice;
class TestBroadcastingEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $notice;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Notice $notice)
{
$this->notice = $notice;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('notice');
}
}
3.3 分發事件
<?php
namespace App\Http\Controllers\Home;
use App\Http\Model\Notice;
use App\Events\TestBroadcastingEvent;
class TestController extends CommonController
{
public function send($id)
{
//當需要給全體發通知的時候觸發
$notice = Notice::find($id);
event(new TestBroadcastingEvent($notice));
}
}
4. 前端監聽
應該還記得前面已經實例化了Echo,現在就是要用這個Echo進行監聽,實現廣播功能
<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>
<script src="/js/app.js"></script>
<script>
<!--上面app.js已經進行了Echo的實例化,然后應該使用實例化的Echo進行廣播事件的監聽-->
console.log(Echo);
Echo.channel('notice')
.listen('TestBroadcastingEvent', (e) => {
// 如果有廣播過來你可以進行邏輯操作,比如給用戶一個通知
console.log(e);
console.log(e.order);
});
5. 查看結果
觸發send()方法進行測試,控制台輸出如下內容
{notice: {…}, socket: null}
{id: 1, content: "感謝你的仔細閱讀,期待共同進步!", created_at: null, updated_at: null}
發現我們后端TestBroadcastingEvent事件類的notice屬性被傳遞過來了,你就可以收到我的感謝了。
6. 整體結構
后端: laravel-echo-server服務器 (通過url地址暴露 socket.io.js)=> 編寫並觸發廣播事件
前端: laravel-echo庫 + 后端暴露的socket.io.js => 實例化Echo => 監聽廣播事件