2016年8月31日 星期三

Laravel 5 Event Broadcasting(事件廣播)進階篇 – Pusher

上一篇:Laravel 5 Event 事件 談到如何使用 Laravel 的 Event(事件),接著我們就要實作比較深入的 Event 功能 – Broadcasting(廣播)
此篇教學會以兩種 Laravel 5.2 所提供的 broadcaster 來當作範例
  1. Pusher
  2. Redis (草稿)
Pusher – 大致上的架構圖
螢幕快照 2016-06-28 下午3.16.11

讓我們以使用者發送訊息的角度來看這個架構圖
1.使用者透過 Ajax 發送訊息給 Laravel 執行 Event (Server 發送訊息) 與新增到 Database
2.Laravel 使用 Event 將資料以Http送給Pusher
3.Client 以 socket 監聽 Pusher 設定的某個 channel 並以添加訊息
安裝環境:
  • Laravel 5.1+
    • Predis  – composer require predis/predis : “~1.1″
    • Pusher – pusher/pusher-php-server : “~2.4.1″

你可能會疑問為什麼 Laravel 官方文件寫 套件 Pusher 只需 ~2.0,但這邊建議 ~2.4.1
套件連結:
這是一個大雷,因為我在 Pusher 2.0 的環境測試了許久,但我的 Pusher 帳戶卻一直沒辦法順利取得訊息
接著就發現 2.0 只會傳給 Pusher us 這個預設 api url,因此套件若您是用 US 則會正常,但你若部署在 eu 或是 ap1 則會出現
Unknown auth_key , code:400 的錯誤,因為他在 us cluster 中找尋不到你的 key
注意此連結程式碼 150行 ~ 158行,就是針對 boardcasting pusher cluster 去設定不同的 host,但 2.0 不支援
2.0 的套件中 options 參數的 cluster 填寫 ap1 要影響 Push $host 這個參數
套件必須在 2.4.1 以後才有支援,否則你得在 broadcasting.php 中多設定 host 參數
.env
PUSHER_KEY=xxxxxxxxxxx
PUSHER_SECRET=xxxxxxxx
PUSHER_APP_ID=xxxxxx
PUSHER_CLUSTER=xxx
view raw.env hosted with ❤ by GitHub
app\Http\routes.php
Route::any('send', 'HomeController@firingEvents');
Route::get('get_pusher', 'HomeController@getPusherMessage');
view rawapp\http\routes.php hosted with ❤ by GitHub
取得不同路徑的呈現方式
config\broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_KEY'),
'secret' => env('PUSHER_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'host' => 'api-ap1.pusher.com', // if pusher/pusher-php-server < 2.4.1.
'cluster' => 'ap1' // require: pusher/pusher-php-server: ~2.4.1
],
],
view rawbroadcasting.php hosted with ❤ by GitHub
broadcasting.php 這邊先設置 pusher driver
別忘了將 default 調整成 pusher
'default' => env('BROADCAST_DRIVER', 'pusher'),
view rawbroadcasting.php hosted with ❤ by GitHub
app\Controllers\HomeController.php
namespace App\Http\Controllers;
use App\Events\SendMessage;
use Illuminate\Http\Request;
use App\Http\Requests;
class HomeController extends Controller
{
public function firingEvents(Request $request)
{
$username = $request->get('username');
$message = $request->get('message');
$user = [
'id' => 10001,
'username' => $username,
];
event(new SendMessage($user, $message));
return 'message sent';
}
public function getPusherMessage()
{
$member_id = 10001;// maybe you can make web notification with Auth.
return view('push')->with(compact('member_id'));
}
}
view rawHomeController.php hosted with ❤ by GitHub
程式第 14 ~ 19 行為根據 get 參數生成一個假的使用者,這裏若是未來要開發當然是可以傳入 Laravel 的 Auth User
第 20 行為觸發此事件。
app\Events\SendMessage.php
namespace App\Events;
use App\User;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class SendMessage extends Event implements ShouldBroadcast
{
use SerializesModels;
private $user;
private $message;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Array $user, $message = '')
{
$this->user = $user;
$this->message = $message;
}
/**
* Payload
*
* @return array
*/
public function broadcastWith()
{
return [
'id' => $this->user['id'],
'username' => $this->user['username'],
'message' => $this->message,
];
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return ['laravel-tutorial-event-channel-'.$this->user['id']];
}
}
view rawSendMessage.php hosted with ❤ by GitHub
函式 broadcastWith() 將想帶入得值寫入,函式 broadcastOn() 將設置此事件的廣播頻道。
views\push.blade.php
<html>
<head>
<title>Laravel</title>
<script src="/bower_components/jquery/dist/jquery.js"></script>
<script src="https://js.pusher.com/3.1/pusher.min.js"></script>
<style>
#message {
height:300px;
width:30%
background-color: #cccccc;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>Laravel Event Broadcasting Demo</h1>
<div id="message">
</div>
</div>
</div>
</div>
</body>
<script>
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
var pusher = new Pusher('{{env('PUSHER_KEY','')}}', {
cluster: 'ap1',
encrypted: true
});
var channel = pusher.subscribe('laravel-tutorial-event-channel-{{$member_id}}');
channel.bind('App\\Events\\SendMessage', function(data) {
$('#message').append(''+data.username + ': '+ data.message + '
'); }); </script> </html>
view rawpush.blade.php hosted with ❤ by GitHub
程式 第 6 行為將 pusher 的函式庫以cdn的方式傳入,程式碼 33 行為設置監聽的頻道與叢集(cluster),第 38 行設置監聽頻道,第 40 行為監聽的 Event 名稱(此例為針對不同使用者應要會取得不同內容)
作者的話:redis 的方法將會在 下一篇與大家說明。

reference : http://codingweb.tw/2016/06/28/laravel-5-event-broadcasting(事件廣播)進階篇-pusher/

沒有留言:

wibiya widget