Pengantar
Laravel Broadcasting memungkinkan kita untuk sharing event yang sama (berikut datanya) antara server-side laravel dan client-side javascript. Salah satu contoh, Dengan Broadcasting, user dapat menerima notifikasi dari aplikasi tanpa harus me-refresh browser.
Pada kesempatan ini saya akan mencoba meng-aplikasikan Laravel Broadcasting dengan Redis dan Socket.IO.
Arsitektur
Step 1 Laravel
Install fresh Laravel
composer create project --prefer-dist laravel/laravel laravelbroadcasting
Masuk directory project dan buat Event
cd laravelbroadcasting && php artisan make:event TestEvent
Supaya Event bisa broadcastable, tambahkan interface ShouldBroadcast dan edit fungsi broadcastOn menjadi return new Channel('test');
// app/Events/TestEvent.php
class TestEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('test');
}
}
Tambahkan route untuk dispatch event
// routes/web.php
Route::get('test-event', function() {
TestEvent::dispatch();
return "OK";
});
Test route test-event
di browser
http://127.0.0.1:8000/test-event
Check log di file storage/logs/laravel.log
[2021-10-04 11:46:53] local.INFO: Broadcasting [App\Events\TestEvent] on channels [test] with payload:
{
"socket": null
}
Event masih broadcast ke log karena BROADCAST_DRIVER=log
di .env
.
Step 2 Queue
Install redis-server jika belum terinstall, dengan:
sudo apt install redis-server
update QUEUE_CONNECTION=sync
menjadi QUEUE_CONNECTION=redis
di file .env dan jalankan perintah:
php artisan queue:work
Broadcast event sudah melewati queue.
Step 3 Redis
update BROADCAST_DRIVER=log
menjadi BROADCAST_DRIVER=redis
di file .env Lalu monitor event dengan:
redis-cli MONITOR
Untuk sementara, broadcast event sudah melewati redis.
Step 4 Socket.IO Server
Install laravel-echo-server
dengan menjalankan perintah:
sudo npm install -g laravel-echo-server
Membuat file konfigurasi laravel-echo-server.json
dengan perintah
laravel-echo-server init
edit file config config/database.php
\\ config/database.php
....
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => '',
],
....
Jalankan perintah php artisan queue:work
, lalu test dengan laravel-echo-server start
Sekarang, event berhasil melewati socket.io server.
Step 5 Socket.IO Client
Install package socket.io-client dan laravel-echo
npm install --save socket.io-client@2.4.0 laravel-echo@1.11.2
Tambah kode di resources/js/bootstrap.js
// resources/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' // host laravel-echo-server
});
Jalan perintah npm install && npm run dev
, lalu edit file resources/views/welcome.blade.php
// resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>
</head>
<body>
<h2>Welcome</h2>
</body>
<script src="{{ asset('js/app.js') }}"></script>
<script>
Echo.channel('test')
.listen("TestEvent", e => {
console.log(e)
})
</script>
</html>
Buka http://127.0.0.1:8000
dan http://127.0.0.1:8000/test-event
di browser di tab yang berbeda.
Jika berhasil, event akan muncul di console browser. Saya coba sisipkan data pada event
// app/Events/TestEvent.php
class TestEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $data = 'Ini data event';
...
Private Channel
Jika ingin menggunakan private channel, ada beberapa file yang akan di config. Client yang ingin menerima event dari private channel diperlukan status authenticated.
Uncomment App\Providers\BroadcastServiceProvider
di config/app.php
, dan edit route channel di file routes/channels.php
// routes/channels.php
Broadcast::channel('test', function ($user) {
return true;
});
Edit laravel echo script di resources/views/welcome.blade.php
// resources/views/welcome.blade.php
...
<script>
Echo.private('test')
.listen('TestEvent', e => {
console.log(e)
})
</script>
Edit app/Events/TestEvent.php
// app/Events/TestEvent.php
...
class TestEvent implements ShouldBroadcast
{
...
public function broadcastOn()
{
return new PrivateChannel('test');
}
}
Jika buka /
di browser, maka akan muncul error log laravel-echo-server Client can not be authenticated, got HTTP status 403
Edit file app/Providers/AppServiceProvider.php
// app/Providers/AppServiceProvider.php
use App\User;
use Illuminate\Support\Facades\Auth;
...
class AppServiceProvider
{
public function boot()
{
$user = User::factory()->make();
Auth::login($user);
}
}
Buka /test-event
dan check log Queueu Worker
, laravel-echo-server
, dan console browser
.
Jika berhasil, event akan muncul di console browser.