Laravel Reverb: WebSocket Real-Time Tanpa Pihak Ketiga

Diperbaharui 5 November 2026 6:04 AM

Selama bertahun-tahun, bikin fitur real-time di Laravel rasanya identik dengan langganan layanan pihak ketiga. Mau notifikasi masuk, chat, atau dashboard yang angkanya berubah sendiri, semuanya lewat Pusher dan tagihan bulanan yang naik seiring jumlah koneksi. Laravel Reverb memutus ketergantungan itu: server WebSocket-nya berjalan di mesin loe sendiri, protokolnya kompatibel dengan Pusher, dan konfigurasinya menyatu dengan sistem broadcasting Laravel yang sudah ada.

Artikel ini membahas Reverb secara praktis untuk Laravel 13, dari composer require sampai catatan produksi. Semua nama perintah dan variabel di bawah diambil dari dokumentasi resmi Laravel dan metadata paket laravel/reverb, bukan dari ingatan.

Apa Itu Laravel Reverb

Reverb adalah paket resmi Laravel yang menyediakan backend komunikasi WebSocket real-time. Ia bukan framework baru dan bukan pengganti Echo. Posisinya di lapisan server: menerima koneksi WebSocket dari browser, mengelola channel, lalu meneruskan pesan yang dipancarkan aplikasi ke semua klien yang berlangganan channel tersebut.

Karena berbicara protokol Pusher, semua tooling yang sudah loe pakai tetap jalan. Laravel Echo di sisi frontend tidak peduli apakah lawan bicaranya server Pusher atau Reverb — cukup ganti beberapa baris konfigurasi.

Versi terbaru yang tercatat di Packagist adalah 1.12.0 (rilis 22 September 2026), dengan syarat PHP ^8.2 dan komponen illuminate/support mulai ^10.47 sampai ^13.0. Artinya paket ini masih bisa dipakai di proyek lama yang tertahan di Laravel 10, asalkan patch-nya cukup baru.

Kapan Reverb Layak Dipakai

Reverb paling masuk akal kalau aplikasi loe butuh notifikasi tanpa refresh, status pesanan yang berubah live, kolaborasi dokumen, atau chat internal. Untuk kebutuhan seperti itu, memelihara satu proses long-running jauh lebih murah daripada membayar per koneksi.

Sebaliknya, kalau yang dibutuhkan hanya pembaruan tiap 30 detik, polling biasa sudah cukup. Menambah WebSocket berarti menambah satu titik yang bisa mati, jadi pastikan manfaatnya sepadan.

Instalasi di Proyek Laravel

Jalur tercepat adalah satu perintah Artisan yang sekaligus memasang paket Composer, dependensi NPM, dan mengisi variabel environment: php artisan install:broadcasting --reverb. Kalau ingin lebih terkendali, pasang manual lewat dua perintah pertama di bawah — hasilnya sama: config/reverb.php terbit, config/broadcasting.php dibuat, dan routes/channels.php disiapkan untuk otorisasi channel.

composer require laravel/reverb
php artisan reverb:install
php artisan reverb:start --debug

Baris terakhir menyalakan server, yang secara default mendengarkan di 0.0.0.0:8080. Flag --debug menampilkan aliran data yang lewat dan berguna saat memastikan event benar-benar terkirim; di server, buang flag itu karena Reverb sengaja tidak mencetak apa pun demi performa. Butuh port lain? Tambahkan --host=127.0.0.1 --port=9000.

Menjalankan Server

Karena prosesnya berumur panjang, perubahan kode tidak akan terbaca sampai loe menjalankan php artisan reverb:restart. Perintah itu menutup koneksi secara rapi lebih dulu, jadi Supervisor bisa langsung menyalakannya lagi tanpa memutus pengguna di tengah jalan.

Konfigurasi Environment yang Wajib Dibenahi

Ada dua kelompok variabel yang gampang tertukar, dan salah menempatkannya adalah sumber error nomor satu saat pertama kali mencoba. REVERB_SERVER_HOST dan REVERB_SERVER_PORT menentukan di mana proses Reverb mendengarkan, sedangkan REVERB_HOST dan REVERB_PORT memberi tahu Laravel ke alamat mana pesan broadcast dikirim.

BROADCAST_CONNECTION=reverb

REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret

REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080

REVERB_HOST=ws.susantokun.com
REVERB_PORT=443
REVERB_SCHEME=https

Di produksi, REVERB_HOST berisi hostname publik dengan port 443, sementara proses Reverb tetap duduk di 0.0.0.0:8080 di belakang reverse proxy. Kalau keduanya disamakan, broadcast akan menembak ke port yang tidak menerima koneksi dari luar.

Daftar origin yang boleh menyambung diatur di config/reverb.php lewat kunci allowed_origins pada tiap entri apps. Origin di luar daftar akan ditolak. Boleh diisi * untuk eksperimen lokal, tapi jangan dibawa ke produksi.

Membuat Event yang Disiarkan

Sisi aplikasi tidak berubah dari cara lama: buat event biasa, lalu implementasikan Illuminate\Contracts\Broadcasting\ShouldBroadcast. Satu method wajib, broadcastOn, mengembalikan channel tujuan. Channel privat dibuat lewat PrivateChannel, dan hanya user yang lolos otorisasi yang bisa mendengarkannya.

namespace App\Events;

use App\Models\Order;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;

class OrderStatusChanged implements ShouldBroadcast
{
    use InteractsWithSockets, SerializesModels;

    public function __construct(public Order $order)
    {
    }

    public function broadcastOn(): array
    {
        return [new PrivateChannel('orders.' . $this->order->id)];
    }

    public function broadcastAs(): string
    {
        return 'order.status.changed';
    }

    public function broadcastWith(): array
    {
        return [
            'id' => $this->order->id,
            'status' => $this->order->status,
        ];
    }
}

Tanpa broadcastWith, seluruh properti publik ikut terkirim apa adanya. Untuk model Eloquent, itu berarti semua kolom — termasuk yang tidak ingin loe bocorkan ke browser. Jadi biasakan menulis payload eksplisit.

Nama dari broadcastAs harus didengarkan dengan titik di depan (.order.status.changed). Tanpa titik itu, Echo menambahkan namespace aplikasi dan listener tidak pernah terpanggil.

Mengamankan Channel Privat

Otorisasi ditulis di routes/channels.php memakai Broadcast::channel. Callback-nya menerima user yang sedang login dan parameter dari nama channel, lalu mengembalikan true atau false. Kalau file itu belum terdaftar, tambahkan argumen channels: pada withRouting di bootstrap/app.php; Laravel biasanya mendaftarkannya otomatis saat broadcasting dipasang.

Menyambung dari Browser dengan Echo

Di sisi frontend, pasang laravel-echo dan pusher-js. Reverb memakai protokol Pusher, jadi pusher-js tetap diperlukan sebagai transport. Setelah itu arahkan Echo ke host Reverb:

import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
});

Nilai VITE_REVERB_* dibaca saat build, jadi setelah mengubah host atau port, jalankan ulang proses build. Ini penyebab umum “kok masih nyambung ke localhost” di staging. Kalau memakai starter kit React, Vue, atau Svelte bawaan Laravel, hook useEcho sudah tersedia dan tidak perlu inisialisasi manual.

Queue Worker Tidak Boleh Lupa

Semua broadcast di Laravel dikirim lewat job antrean, kecuali driver Mercure. Artinya tanpa worker yang hidup, event tidak akan pernah sampai ke browser meski aplikasi terlihat normal. Jalankan php artisan queue:work di server dan awasi prosesnya seperti Reverb. Kalau butuh siaran segera tanpa antrean, ada varian ShouldBroadcastNow — tapi request HTTP jadi menunggu pengiriman selesai, dan itu memperlambat response pada trafik tinggi.

Menyiapkan Reverb di Server Produksi

Reverb biasanya tidak menghadap internet langsung. Pasang reverse proxy Nginx yang meneruskan header Upgrade dan Connection, lalu arahkan ke port internal. Dua URI harus bisa dilayani: /app untuk koneksi WebSocket dan /apps untuk permintaan API. Tanpa header upgrade, koneksi jatuh ke HTTP biasa dan langsung putus.

Batas file terbuka adalah jebakan berikutnya. Setiap koneksi memakan satu file descriptor, jadi angka default 1.024 cepat habis. Naikkan lewat /etc/security/limits.conf, lalu sesuaikan juga minfds di Supervisor dan worker_rlimit_nofile di Nginx agar semuanya sejalan. Untuk melewati 1.000 koneksi bersamaan, Reverb butuh event loop yang tidak terikat stream_select; ekstensi ext-uv dari PECL dipakai otomatis begitu tersedia.

Terakhir, pantau lewat Laravel Pulse. Reverb menyediakan recorder ReverbConnections dan ReverbMessages yang didaftarkan di config/pulse.php, plus daemon pulse:check yang wajib hidup — cukup di satu server saja meski Reverb-nya banyak.

Scaling Horizontal dengan Redis

Satu proses Reverb punya plafon. Kalau koneksi mulai menembus batas memori atau file descriptor, aktifkan REVERB_SCALING_ENABLED=true dan sediakan satu Redis pusat. Setiap node memakai Redis untuk publish/subscribe, sehingga pesan yang masuk ke satu server ikut disebar ke node lain di belakang load balancer.

Praktik yang Menghemat Waktu Debugging

  • Uji dengan dua browser berbeda, bukan dua tab — dua tab berbagi sesi dan cookie yang sama sehingga hasilnya menyesatkan.
  • Periksa /broadcasting/auth di tab Network sebelum menyalahkan Reverb; 403 di situ berarti masalah otorisasi channel, bukan koneksi.
  • Simpan payload kecil: kirim ID, lalu biarkan klien mengambil detail lewat API daripada mengirim model utuh.
  • Gunakan channel publik hanya untuk data yang memang boleh dibaca siapa pun.

FAQ

Apakah Reverb bisa menggantikan Pusher tanpa mengubah kode frontend?

Sebagian besar bisa. Karena protokolnya kompatibel, cukup ganti broadcaster menjadi reverb lalu sesuaikan host dan key. Logic channel dan listener tetap sama.

Kenapa event terkirim tapi tidak muncul di browser?

Urutan pemeriksaan tercepat: worker antrean hidup, nama listener memakai titik di depan kalau memakai broadcastAs, lalu origin klien ada di allowed_origins. Tiga hal itu menyumbang mayoritas kasus.

Apakah wajib memakai Redis?

Tidak, selama hanya ada satu proses Reverb. Redis baru dibutuhkan ketika loe mengaktifkan scaling horizontal.

Kesimpulan

Laravel Reverb memberi loe kendali penuh atas lapisan real-time tanpa menulis ulang arsitektur broadcasting. Biaya masuknya moderat: satu proses tambahan, satu worker antrean, dan beberapa baris konfigurasi yang harus tepat. Sebagai imbalannya, tidak ada lagi kuota koneksi yang perlu dihitung setiap bulan.

Kalau aplikasi loe sudah memakai event dan queue, migrasi ke Reverb terasa seperti menambah driver, bukan membangun sistem baru. Untuk langkah berikutnya, lihat juga integrasi Laravel AI SDK yang memakai pola event serupa, pelajari kembali relasi tabel di Eloquent untuk merancang channel per entitas, dan cek fitur PHP 8.5 yang bisa merapikan kode event loe.

Referensi

susantokun avatar
susantokun
Hanya seorang programmer yang fokus di bidang web development. Tidak nyaman dengan keramaian dan suka akan keindahan.
Kebijakan Berkomentar :
1. Dilarang berkomentar yang mengandung SPAM, SARA, HOAX, PORNO.2. Mohon sertakan informasi detail saat terjadi error (pesan error, sreenshoot, code, logs, dsb.).