Pengenalan WebSocket & Realtime

Anda membuat dashboard pesanan. Setiap kali ada pesanan baru, admin harus menekan tombol refresh untuk melihatnya. Untuk memperbaikinya, banyak developer pemula menambahkan setInte...

Pengenalan WebSocket & Realtime

Anda membuat dashboard pesanan. Setiap kali ada pesanan baru, admin harus menekan tombol refresh untuk melihatnya. Untuk memperbaikinya, banyak developer pemula menambahkan setInterval yang memanggil server tiap tiga detik. Hasilnya jalan, tetapi server dibombardir ratusan request kosong per menit hanya untuk mendengar jawaban "belum ada yang baru". WebSocket dibuat untuk masalah ini: server yang mengabari browser saat ada kejadian, bukan browser yang terus bertanya.

Bagaimana WebSocket Berbeda dari HTTP Biasa

HTTP bekerja dengan pola tanya-jawab. Browser mengirim request, server menjawab, lalu koneksi selesai. Server tidak bisa memulai percakapan. Itulah mengapa teknik lama seperti polling (bertanya berulang) dan long polling (bertanya lalu menunggu lama) muncul sebagai akal-akalan.

WebSocket memulai dengan request HTTP biasa yang meminta "upgrade", lalu koneksi TCP yang sama dibiarkan terbuka dua arah. Selama koneksi hidup, server maupun browser bebas mengirim pesan kapan saja tanpa header berulang. Overhead per pesan hanya beberapa byte, sehingga cocok untuk notifikasi, chat, status pesanan, papan skor, dan indikator "sedang mengetik".

Kapan WebSocket layak dipakai

  • Layak: notifikasi langsung, chat, dashboard monitoring, kolaborasi dokumen, antrean pesanan dapur.
  • Tidak perlu: data yang cukup diperbarui tiap beberapa menit, laporan bulanan, atau halaman yang jarang berubah. Polling sederhana tiap 30 detik lebih murah dan lebih mudah dirawat.
  • Alternatif ringan: Server-Sent Events untuk aliran satu arah (server ke browser) tanpa perlu server WebSocket terpisah.

Arsitektur Broadcasting di Laravel

Laravel tidak menjalankan WebSocket di dalam proses PHP-FPM biasa, karena PHP-FPM dirancang untuk request pendek. Sebagai gantinya ada tiga bagian yang bekerja sama:

  1. Event di aplikasi Anda, misalnya PesananDibuat, yang ditandai ShouldBroadcast.
  2. Server WebSocket yang menjaga koneksi terbuka. Sejak Laravel 11 tersedia Reverb, server first-party yang ditulis dengan PHP dan ReactPHP. Pilihan lain: Pusher, Ably, atau Soketi.
  3. Laravel Echo di sisi browser yang berlangganan channel dan menjalankan callback saat pesan datang.

Alurnya: aplikasi men-dispatch event, event masuk antrean, worker mengirimkannya ke server Reverb, lalu Reverb meneruskan ke semua browser yang berlangganan channel tersebut.

Langkah Praktis: Notifikasi Pesanan Realtime

1. Pasang broadcasting dan Reverb

Di Laravel 11 broadcasting tidak aktif secara bawaan. Satu perintah memasangnya beserta Reverb:

php artisan install:broadcasting
# jawab "yes" saat ditanya soal Reverb, lalu pastikan .env terisi:
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=local-app
REVERB_APP_KEY=kunci-acak-anda
REVERB_APP_SECRET=rahasia-acak-anda
REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http

Jalankan server di terminal terpisah selama pengembangan:

php artisan reverb:start --debug

2. Buat event yang di-broadcast

php artisan make:event PesananDibuat
<?php

namespace App\Events;

use App\Models\Pesanan;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class PesananDibuat implements ShouldBroadcast
{
    use Dispatchable, SerializesModels;

    public function __construct(public Pesanan $pesanan) {}

    public function broadcastOn(): array
    {
        // Channel privat: hanya admin yang boleh mendengarkan.
        return [new PrivateChannel('admin.pesanan')];
    }

    public function broadcastWith(): array
    {
        // Kirim data seperlunya saja, jangan seluruh model.
        return [
            'id'    => $this->pesanan->id,
            'nama'  => $this->pesanan->nama_pelanggan,
            'total' => $this->pesanan->total,
        ];
    }
}

Panggil dari tempat pesanan disimpan:

$pesanan = Pesanan::create($data);
PesananDibuat::dispatch($pesanan);

3. Otorisasi channel privat

Channel privat butuh aturan siapa yang boleh bergabung. Tanpa langkah ini, siapa pun yang tahu nama channel bisa menguping data pesanan. Daftarkan di routes/channels.php:

Broadcast::channel('admin.pesanan', function ($user) {
    return $user->role === 'admin';
});

4. Dengarkan di browser dengan Echo

npm install --save-dev laravel-echo pusher-js
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'],
});

Echo.private('admin.pesanan')
    .listen('PesananDibuat', (e) => {
        tambahBarisPesanan(e);   // perbarui tabel tanpa refresh
    });

Nama event yang didengarkan sama dengan nama kelasnya. Bila Anda ingin nama lain, definisikan broadcastAs() di event.

Masalah yang Sering Menjebak

Event tidak sampai karena antrean tidak jalan

Event ShouldBroadcast dikirim lewat queue. Jika QUEUE_CONNECTION=database dan tidak ada worker berjalan, event menumpuk di tabel jobs dan browser tidak menerima apa pun. Jalankan php artisan queue:work. Untuk event yang harus langsung terkirim tanpa worker, gunakan ShouldBroadcastNow, dengan konsekuensi request pengguna menunggu pengiriman selesai.

Mixed content di produksi

Halaman HTTPS tidak boleh membuka koneksi ws:// biasa. Gunakan wss://, artinya server WebSocket perlu berada di belakang reverse proxy (Nginx atau Caddy) yang menangani TLS. Konfigurasi Nginx harus menyertakan header Upgrade dan Connection, kalau tidak koneksi akan terputus setelah handshake.

Proses harus terus hidup

reverb:start adalah proses panjang. Di server, jalankan di bawah Supervisor atau systemd agar otomatis hidup lagi saat crash atau reboot. Setelah deploy, kirim php artisan reverb:restart agar kode baru terbaca.

Shared hosting umumnya tidak cocok

Shared hosting biasanya melarang proses yang berjalan terus dan tidak membuka port kustom. Jika proyek Anda berada di sana, pilihannya VPS kecil atau layanan terkelola seperti Pusher atau Ably, yang cukup mengubah BROADCAST_CONNECTION dan kredensial tanpa mengubah kode event.

Menguji Tanpa Menunggu Browser

Anda tidak perlu membuka dua tab setiap kali menguji. Gunakan Event::fake() di test untuk memastikan event benar-benar di-dispatch saat pesanan dibuat, lalu uji otorisasi channel secara terpisah.

public function test_pesanan_baru_memicu_broadcast(): void
{
    Event::fake([PesananDibuat::class]);

    $this->actingAs(User::factory()->create(['role' => 'admin']))
        ->post('/pesanan', ['nama_pelanggan' => 'Budi', 'total' => 50000]);

    Event::assertDispatched(PesananDibuat::class);
}

Untuk melihat pesan yang sebenarnya lewat, jalankan reverb:start --debug. Terminal akan mencetak tiap koneksi masuk, langganan channel, dan pesan yang diteruskan, sehingga mudah memisahkan masalah di backend dari masalah di sisi browser.

Checklist Sebelum Go-Live

  • Channel sensitif memakai PrivateChannel dengan aturan di routes/channels.php.
  • broadcastWith() hanya mengirim field yang dibutuhkan.
  • Worker queue dan Reverb berjalan di bawah Supervisor.
  • Koneksi memakai wss:// lewat reverse proxy dengan header upgrade.
  • Browser punya cadangan: bila koneksi putus, halaman tetap bisa memuat ulang data lewat tombol refresh atau polling pelan.

Fitur realtime paling berguna bila data yang dikirim juga efisien. Pelajari caching di Laravel untuk mengurangi beban query saat banyak klien memperbarui tampilan, dan queue dan job Laravel untuk memastikan worker berjalan stabil.

Ingin langsung mempraktikkannya?

Buat akun gratis untuk mengunduh contoh aplikasi Laravel, menyimpan tutorial favorit, dan mencoba kursus. Gratis, bisa daftar dengan akun Google.

Daftar Gratis Lihat katalog aplikasi
Yudhi
Ditulis oleh
Yudhi
Founder & Lead Developer, GudangCode

Yudhi adalah founder GudangCode dan developer Laravel dengan pengalaman membangun puluhan sistem informasi bisnis siap pakai — mulai dari POS, HRIS, hingga aplikasi manajemen. Ia menulis panduan dan artikel di GudangCode untuk membantu developer Indonesia menjalankan, memahami, dan men-deploy source code Laravel dengan benar.

Laravel PHP MySQL Sistem Informasi Bisnis
Lihat semua artikel Yudhi
Websocket Realtime Teknologi & Development
Bacaan Paling Dicari
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →