Hampir semua yang Anda buka di browser bekerja dengan pola HTTP yang sama: browser mengirim permintaan, web server membalas, lalu urusan selesai. Pola tanya-jawab ini sederhana dan sangat cocok untuk membuka halaman artikel atau mengunduh gambar. Namun, ada satu hal yang tidak bisa dilakukan HTTP biasa: server tidak bisa berbicara lebih dulu. Selama browser tidak bertanya, kabar baru di server hanya tersimpan diam di sana.
Masalah itu terasa begitu aplikasi butuh data yang berubah setiap detik, seperti pesan chat, papan skor, atau status pesanan. WebSocket adalah protokol yang dibuat untuk menjawab keterbatasan tersebut. Di artikel ini kita akan membahas apa itu WebSocket dan apa yang terjadi di jaringan saat koneksinya dibuka. Setelah itu, kita bandingkan dengan HTTP, SSE, webhook, dan polling, lalu melihat angka yang perlu Anda siapkan sebelum menjalankannya di server.
Apa Itu WebSocket?
WebSocket adalah protokol komunikasi dua arah yang berjalan di atas satu koneksi TCP yang dibiarkan tetap terbuka. Setelah koneksi tersambung, klien dan server sama-sama bisa mengirim pesan kapan saja tanpa menunggu giliran. Sifat ini disebut full-duplex (kedua arah aktif bersamaan).
Bayangkan perbedaan antara loket informasi dan interkom. Di loket, Anda harus datang, bertanya, menerima jawaban, lalu pergi; kalau ingin tahu lagi, Anda antre lagi. Interkom berbeda. Sekali sambungannya dinyalakan, kedua ruangan bisa bicara kapan pun ada yang perlu disampaikan. HTTP bekerja seperti loket, sedangkan WebSocket bekerja seperti interkom.
Istilah "WebSocket" sebenarnya merujuk ke dua hal yang sering tertukar:
- Protokol WebSocket: aturan di level jaringan tentang cara membuka koneksi, membungkus pesan, dan menutupnya. Aturan ini dibakukan dalam RFC 6455.
- WebSocket API: antarmuka di browser, yaitu objek
WebSocketdi JavaScript yang dipakai developer untuk membuka koneksi tersebut. API ini dipelihara WHATWG dan tersedia di semua browser utama sejak Juli 2015 menurut MDN.
Saat orang bertanya "web socket adalah apa", jawabannya hampir selalu mencakup keduanya: protokol yang bekerja di jaringan dan API yang memanggilnya dari kode.
Dari TCPConnection ke RFC 6455: Riwayat Singkat
WebSocket berawal dari draf spesifikasi HTML5 dengan nama sementara TCPConnection. Pada Juni 2008, diskusi yang dipimpin Michael Carter menghasilkan versi pertama protokolnya. Nama "WebSocket" kemudian dicetuskan oleh Ian Hickson dan Michael Carter.
Google Chrome 4 menjadi browser pertama yang mengaktifkannya secara bawaan pada Desember 2009. Pengembangan protokol lalu pindah ke IETF pada Februari 2010, dan RFC 6455 terbit sebagai standar pada Desember 2011. Setelah itu muncul beberapa tambahan:
- RFC 7692: kompresi pesan dengan algoritma DEFLATE (permessage-deflate).
- RFC 8441 (2018): cara membuka WebSocket di dalam satu stream HTTP/2.
- RFC 9220 (2022): mekanisme yang sama untuk HTTP/3.
Riwayat ini menjelaskan satu keputusan desain penting. WebSocket sengaja dibuat "menumpang" HTTP supaya bisa memakai port yang sama dengan website dan lolos dari firewall yang sudah ada.
Cara Kerja WebSocket: Handshake, Frame, lalu Penutupan
Satu koneksi WebSocket melewati tiga fase: handshake (jabat tangan pembuka), pertukaran frame (potongan pesan), dan penutupan. Ketiganya bisa Anda amati sendiri di tab Network pada DevTools browser, dengan filter "WS".

Handshake: HTTP Minta Izin Berganti Protokol
Koneksi WebSocket selalu dimulai sebagai permintaan HTTP biasa. Bedanya, permintaan ini membawa header yang meminta server berganti protokol:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.comKalau server setuju, ia membalas dengan kode status 101 Switching Protocols:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Kode selain 101 berarti handshake gagal dan koneksi tidak pernah menjadi WebSocket. Setelah balasan 101 diterima, HTTP selesai bertugas. Koneksi TCP yang sama kini dipakai untuk lalu lintas WebSocket.
Nilai Sec-WebSocket-Accept tidak dibuat asal. Server menggabungkan Sec-WebSocket-Key dari klien dengan string tetap 258EAFA5-E914-47DA-95CA-C5AB0DC85B11, menghitung hash SHA-1, lalu mengubahnya ke base64. Anda bisa membuktikannya di terminal:
KEY='dGhlIHNhbXBsZSBub25jZQ=='
GUID='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
printf '%s' "$KEY$GUID" \
| openssl dgst -sha1 -binary \
| openssl base64Hasilnya s3pPLMBiTxaQ9kYGzzhZRbK+xOo=, sama persis dengan balasan server. Saat kami mengirim handshake ini ke server uji publik echo.websocket.org, balasannya pun berisi nilai yang sama. Perlu diperhatikan, mekanisme ini hanya membuktikan bahwa server memang memahami WebSocket. Ia bukan alat autentikasi.
Frame: Pesan Kecil dengan Header 2–14 Byte
Setelah handshake, data dikirim dalam bentuk frame. Header satu frame minimal hanya 2 byte. Header bertambah menjadi paling banyak 14 byte untuk pesan yang sangat besar atau yang dikirim dari klien. Bandingkan dengan header permintaan HTTP yang biasanya berukuran ratusan byte.
Setiap frame membawa opcode yang menandai jenis isinya:
- 0x1 (teks): pesan teks UTF-8, misalnya JSON.
- 0x2 (biner): data mentah seperti potongan audio atau gambar.
- 0x8 (close): permintaan menutup koneksi.
- 0x9 dan 0xA (ping dan pong): pemeriksaan apakah lawan bicara masih hidup.
Ada satu aturan yang terlihat aneh: setiap frame dari klien ke server wajib di-mask (diacak dengan kunci 4 byte yang berbeda tiap frame). Aturan ini melindungi proxy lama di jalur jaringan. Tanpa masking, skrip jahat bisa menyusun byte yang terlihat seperti permintaan HTTP dan meracuni cache proxy tersebut.
Ping, Pong, dan Kode Penutupan
Koneksi yang lama diam berisiko diputus oleh perangkat di tengah jalan. Untuk itu, salah satu pihak bisa mengirim frame ping, dan pihak lain wajib membalas pong dengan isi yang sama. Pola ini dikenal sebagai heartbeat.
Saat koneksi ditutup dengan benar, kedua pihak bertukar frame close yang membawa kode status. Kode yang paling sering Anda temui:
| Kode | Arti |
|---|---|
| 1000 | Penutupan normal, tugas koneksi sudah selesai |
| 1001 | Pihak lain pergi, misalnya server dimatikan atau pengguna pindah halaman |
| 1006 | Koneksi putus tanpa frame close sama sekali |
| 1008 | Pesan melanggar kebijakan server |
| 1009 | Pesan terlalu besar untuk diproses |
| 1011 | Server mengalami kondisi tak terduga |
Kode 1006 perlu mendapat perhatian khusus. RFC 6455 melarang kode ini dikirim lewat jaringan. Browser-lah yang menuliskannya sendiri ketika koneksi hilang begitu saja, misalnya karena timeout di proxy, jaringan terputus, atau proses server mati mendadak.
Contoh WebSocket di Browser dengan JavaScript
Membuka koneksi WebSocket dari JavaScript cukup mudah. Kode berikut membuka koneksi ke server uji publik, mengirim satu pesan JSON, mencetak semua balasan, lalu menutup koneksi setelah tiga detik:
const url = 'wss://echo.websocket.org';
const socket = new WebSocket(url);
socket.addEventListener('open', () => {
console.log('Terhubung:', socket.readyState);
const pesan = { tipe: 'sapa', isi: 'Halo' };
socket.send(JSON.stringify(pesan));
});
socket.addEventListener('message', (e) => {
console.log('Diterima:', e.data);
});
socket.addEventListener('close', (e) => {
console.log('Tertutup, kode:', e.code);
});
setTimeout(() => socket.close(1000), 3000);Saat kami menjalankannya, keluarannya seperti ini:
Terhubung: 1
Diterima: Request served by 4d896d95b55478
Diterima: {"tipe":"sapa","isi":"Halo"}
Tertutup, kode: 1000Baris kedua adalah sapaan bawaan server uji, sedangkan baris ketiga adalah pesan kita yang dipantulkan kembali. Nilai readyState 1 berarti koneksi sudah terbuka. Kode yang sama berjalan di console browser maupun di Node.js versi 22 ke atas.
Kode di atas adalah WebSocket client. Di browser, klien tidak membutuhkan pustaka tambahan, termasuk saat Anda memakai React atau Vue. Sebaliknya, WebSocket server selalu membutuhkan pustaka sesuai bahasanya:
- Node.js: pustaka
ws, atau Socket.IO bila Anda butuh fitur tambahan seperti room. - PHP dan Laravel: Laravel Reverb, server WebSocket resmi yang secara bawaan berjalan di
0.0.0.0:8080. Di sisi browser, ia dipasangkan dengan Laravel Echo untuk mendengarkan event. - Python: pustaka
websocketsberbasis asyncio, atau dukungan WebSocket bawaan di FastAPI. - Go (Golang):
gorilla/websocketyang paling banyak dipakai. - Flutter: paket
web_socket_channeluntuk sisi klien di aplikasi mobile.
WS dan WSS: Port, Enkripsi, dan TCP atau UDP
WebSocket punya dua skema alamat. ws:// adalah koneksi tanpa enkripsi yang memakai port 80 secara bawaan. wss:// adalah WebSocket di atas TLS yang memakai port 443, hubungannya sama seperti HTTP dengan HTTPS.
Gunakan wss:// untuk semua koneksi di internet. Selain mengenkripsi isi pesan, wss:// lebih jarang diganggu perangkat perantara karena isinya tidak bisa dibaca di jalan. Browser juga memblokir ws:// yang dibuka dari halaman HTTPS sebagai mixed content.

WebSocket selalu berjalan di atas TCP, bukan UDP. Artinya, setiap pesan pasti sampai dan urutannya terjaga. Kalau aplikasi Anda justru butuh data yang boleh hilang demi kecepatan, misalnya posisi pemain di game, browser menyediakan WebTransport yang berjalan di atas QUIC/UDP.
Contoh Penggunaan WebSocket di Aplikasi Nyata
WebSocket sering bekerja tanpa terlihat. Beberapa contoh berikut mungkin sudah Anda pakai:
- Harga kripto dan saham: bursa seperti Binance mengalirkan setiap transaksi lewat alamat
wss://stream.binance.com:9443. Grafik harga di aplikasi bergerak tanpa memuat ulang halaman. - Kendali OBS Studio: sejak versi 28, OBS menyertakan server WebSocket di port 4455. Aplikasi di ponsel atau Stream Deck memakainya untuk berganti adegan saat siaran.
- Rumah pintar: Home Assistant menyediakan API WebSocket di
/api/websocket. Antarmukanya memakai jalur ini untuk menerima perubahan status lampu atau sensor seketika. - Minecraft Bedrock dan Education: perintah
/connect(alias/wsserver) menyambungkan dunia permainan ke server WebSocket. Fitur ini dipakai alat belajar pemrograman seperti Code Connection. - Chat, notifikasi, dan dokumen bersama: pesan baru, indikator "sedang mengetik", dan kursor rekan kerja di dokumen yang sama adalah kasus klasik WebSocket.
WebSocket vs HTTP, SSE, Webhook, dan Polling
WebSocket bukan satu-satunya cara mengirim data "langsung" ke pengguna. Tabel berikut merangkum perbedaannya:
| Teknik | Arah data | Cocok untuk |
|---|---|---|
| HTTP | Tanya-jawab | Halaman, API umum |
| Polling | Klien bertanya berulang | Data jarang berubah |
| SSE | Server ke klien | Notifikasi, progres |
| Webhook | Server ke server | Pembayaran, integrasi |
| WebSocket | Dua arah, terus terbuka | Chat, game, dasbor |
WebSocket vs HTTP. HTTP menutup siklus di setiap permintaan, dan server tidak bisa mengirim apa pun tanpa diminta. Itulah sebabnya REST API tetap jadi pilihan untuk operasi biasa seperti mengambil daftar produk. WebSocket baru unggul ketika pesan mengalir sering dan dari dua arah.
WebSocket vs SSE. SSE (Server-Sent Events) hanya mengalirkan data dari server ke browser, lewat HTTP biasa. Kalau klien jarang mengirim apa pun, SSE lebih sederhana. Namun, tanpa HTTP/2, browser membatasi SSE hingga 6 koneksi per domain untuk semua tab sekaligus.
Webhook vs WebSocket. Webhook adalah permintaan HTTP dari satu server ke server lain saat ada kejadian, misalnya pembayaran berhasil. Webhook tidak menjaga koneksi apa pun dan tidak ditujukan ke browser pengguna.
Polling vs WebSocket. Selisihnya paling terasa saat dihitung. Misalkan browser bertanya ke server setiap 1 detik, dan satu pasang permintaan-balasan membawa 800 byte header. Dalam satu jam, satu pengguna menghasilkan 3.600 permintaan atau sekitar 2,88 MB header, walaupun tidak ada data baru sama sekali. Dengan 1.000 pengguna, angkanya menjadi 2,88 GB per jam.
WebSocket dengan ping setiap 30 detik hanya bertukar 120 pasang ping-pong per jam. Ping dari server berheader 2 byte dan pong dari klien 6 byte, sehingga totalnya sekitar 960 byte per pengguna. Angka 800 byte itu pun tergolong kecil: halaman blog ini sendiri dibalas dengan header 2.129 byte saat kami ukur.

Satu hal lagi sering membingungkan: Socket.IO bukan WebSocket. Dokumentasi resminya menegaskan bahwa klien WebSocket biasa tidak bisa terhubung ke server Socket.IO, begitu pula sebaliknya. Socket.IO memakai WebSocket sebagai salah satu jalur, lalu menambahkan protokolnya sendiri di atasnya.
Tiga protokol lain juga sering dibandingkan dengan WebSocket, padahal perannya berbeda:
- MQTT: protokol publish/subscribe lewat perantara (broker) yang populer untuk perangkat IoT. Browser tidak bisa berbicara MQTT langsung, sehingga MQTT di halaman web justru berjalan di atas WebSocket.
- gRPC: kerangka RPC di atas HTTP/2 untuk komunikasi antarlayanan. Di browser, gRPC-Web hanya mendukung panggilan biasa dan streaming dari server, tanpa streaming dua arah.
- WebRTC: komunikasi langsung antarbrowser untuk audio, video, dan data. WebRTC tetap membutuhkan saluran untuk saling bertukar alamat, dan saluran itu sering kali berupa WebSocket.
Kelebihan WebSocket
- Latensi rendah: data dikirim begitu tersedia, bukan menunggu jadwal polling berikutnya atau koneksi baru. Ini memangkas latency antara kejadian di server dan tampilan di layar pengguna.
- Server bisa mengirim lebih dulu: kabar baru langsung didorong ke klien tanpa menunggu ditanya.
- Overhead kecil per pesan: header frame 2–14 byte, jauh di bawah header HTTP yang berukuran ratusan hingga ribuan byte.
- Satu koneksi untuk dua arah: klien dan server tidak perlu membuka jalur terpisah untuk mengirim dan menerima.
- Didukung luas: semua browser utama mendukungnya, dan port 80/443 yang dipakai jarang diblokir firewall kantor.
Kekurangan WebSocket dan Hal yang Perlu Dipertimbangkan
- Koneksi berstatus: setiap pengguna terikat ke satu proses server tertentu. Saat server lebih dari satu, Anda butuh load balancing dengan session affinity dan perantara seperti Redis untuk menyebarkan pesan ke semua server.
- Tidak ada sambung ulang otomatis: API
WebSocketdi browser tidak menyambung ulang saat koneksi putus dan tidak menyimpan pesan yang gagal terkirim. Logika itu harus Anda tulis sendiri. - Tanpa pengatur laju (backpressure): MDN mencatat bahwa bila pesan datang lebih cepat daripada kemampuan aplikasi memprosesnya, memori bisa penuh atau CPU bisa terpakai 100%.
- Rentan diputus perantara: Nginx menutup koneksi yang diam 60 detik secara bawaan. Cloudflare juga menutup koneksi yang menganggur, dan koneksi ikut terputus saat servernya di-restart untuk rilis kode.
- Tidak bisa di-cache: untuk data yang jarang berubah, HTTP dengan cache jauh lebih hemat.
- Tidak dilindungi same-origin policy: situs lain bisa mencoba membuka koneksi ke server Anda. Bila handshake hanya mengandalkan cookies, penyerang bisa membaca data korban lewat serangan Cross-Site WebSocket Hijacking. Server wajib memeriksa header
Origindan meminta token.
Praktik Terbaik Menjalankan Server WebSocket
Server WebSocket adalah proses yang terus hidup dan memegang ribuan koneksi sekaligus. Pekerjaan pertama biasanya ada di reverse proxy. Header Upgrade tidak diteruskan otomatis oleh proxy, jadi di Nginx Anda perlu menambahkan baris berikut di blok location yang mengarah ke server WebSocket:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 120s;Untuk Nginx sebelum versi 1.29.7, tambahkan juga proxy_http_version 1.1;. Tanpa header tersebut, browser biasanya menampilkan "WebSocket connection failed" karena handshake tidak pernah mendapat balasan 101.
Setelah proxy beres, beberapa angka berikut menentukan apakah server Anda sanggup menahan banyak koneksi:
- Kirim ping setiap 25–30 detik: interval ini berada di bawah batas 60 detik Nginx dan cukup jarang untuk tidak membebani jaringan. Cara ini lebih andal daripada sekadar menaikkan timeout.
- Naikkan batas file terbuka: setiap koneksi dihitung sebagai satu file terbuka di Linux. Periksa dengan
ulimit -n, lalu naikkan misalnya ke 10.000 lewat/etc/security/limits.conf. Dokumentasi Laravel Reverb mencatat event loop bawaannya terbatas pada 1.024 file, sehingga lebih dari 1.000 koneksi butuh ekstensiext-uv. - Perhatikan rentang port lokal: rentang bawaan
32768–60999di Linux berarti sekitar 28.231 koneksi keluar dari satu alamat IP. Batas ini berlaku saat proxy membuka koneksi ke backend, jadi di atas angka itu sebaiknya server ditambah, bukan dipaksa. - Jaga prosesnya tetap hidup: gunakan Supervisor atau PM2 supaya server WebSocket otomatis menyala lagi setelah crash atau reboot.
Semua pengaturan di atas membutuhkan akses root ke sistem operasi. Itulah sebabnya server WebSocket umumnya dijalankan di VPS, tempat Anda bebas mengatur ulimit, Nginx, dan pengelola proses.
Cara Menguji Koneksi WebSocket
Sebelum mencurigai kode aplikasi, pastikan dulu koneksinya memang terbuka. Ada tiga alat uji (WebSocket tester) yang tidak membutuhkan instalasi rumit. Untuk lawan bicaranya, Anda bisa memakai server uji online echo.websocket.org yang memantulkan setiap pesan.
Lewat DevTools Browser
Buka DevTools, masuk ke tab Network, lalu klik filter WS. Klik nama koneksinya dan buka tab Messages. Pesan keluar ditandai hijau muda, pesan masuk berlatar putih, dan pesan error berwarna merah muda. Tabel ini menyimpan 100 pesan terakhir.
Lewat curl di Terminal
Perintah berikut mengirim handshake yang sama seperti browser dan menampilkan balasan server:
KEY='dGhlIHNhbXBsZSBub25jZQ=='
curl -i -N --http1.1 \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: $KEY" \
https://echo.websocket.org/Server yang sehat membalas HTTP/1.1 101 Switching Protocols, lalu curl menunggu karena koneksinya tetap terbuka. Tekan Ctrl+C untuk keluar. Kalau yang muncul kode lain, cocokkan dengan tabel di bagian pertanyaan di bawah.

Lewat Postman
Postman menyediakan jenis permintaan WebSocket. Masukkan alamat wss://, klik Connect, lalu kirim pesan teks atau JSON dan lihat balasannya di panel yang sama. Cara ini cocok untuk menguji server sebelum antarmuka browsernya selesai dibuat.
Pertanyaan Seputar WebSocket
WSS itu apa?
WSS adalah WebSocket Secure, yaitu WebSocket yang berjalan di atas TLS dengan alamat berawalan wss:// dan port 443. Fungsinya sama dengan HTTPS bagi HTTP: isi pesan terenkripsi dan identitas server diverifikasi lewat sertifikat.
Apa itu SSH WebSocket (SSHWS)?
SSH WebSocket adalah cara membungkus koneksi SSH di dalam koneksi WebSocket. Server menerima koneksi WebSocket lalu meneruskannya ke layanan SSH di dalam mesin. Teknik ini dipakai agar SSH bisa melewati CDN atau proxy yang hanya meneruskan lalu lintas HTTP dan HTTPS.

Apakah Socket.IO sama dengan WebSocket?
Tidak. Socket.IO adalah pustaka dengan protokolnya sendiri yang bisa memakai WebSocket, HTTP long-polling, atau WebTransport sebagai jalur. Klien WebSocket biasa tidak bisa terhubung ke server Socket.IO tanpa pustaka Socket.IO di sisi klien.
Kenapa muncul "WebSocket connection failed" atau kode 1006?
Pesan "connection failed" berarti handshake tidak mendapat balasan 101. Kode status HTTP yang dikirim server biasanya menunjukkan penyebabnya:
| Kode | Penyebab umum |
|---|---|
| 400 | Header handshake salah atau versi tak didukung |
| 401 | Butuh login atau token |
| 403 | Origin ditolak server |
| 426 | Server meminta versi protokol lain |
| 502/504 | Proxy gagal atau terlambat menghubungi backend |
Kode 400 dan 426 biasanya disertai header Sec-WebSocket-Version yang menyebut versi yang diterima server. Saat kami mengirim versi 8 ke server uji, balasannya 400 Bad Request dengan Sec-WebSocket-Version: 13.
Kode 1006 berbeda, karena muncul setelah koneksi sempat terbuka. Kode ini berarti koneksi putus tanpa frame close, biasanya karena timeout di proxy, jaringan klien terputus, atau proses server mati.
Apakah WebSocket bisa berjalan di HTTP/2 dan HTTP/3?
Bisa secara standar, lewat RFC 8441 untuk HTTP/2 dan RFC 9220 untuk HTTP/3. Dalam praktik, sebagian besar koneksi WebSocket di browser masih dibuka lewat handshake HTTP/1.1, karena dukungan browser dan server untuk kedua RFC tersebut belum merata.
Kesimpulan
WebSocket adalah protokol yang mengubah satu permintaan HTTP menjadi koneksi TCP dua arah yang tetap terbuka, sehingga server bisa mengirim data tanpa menunggu ditanya. Kekuatannya ada pada latensi rendah dan overhead kecil per pesan. Konsekuensinya, Anda perlu mengurus sambung ulang, ping berkala, batas file terbuka, dan pemeriksaan Origin sendiri.
Gunakan WebSocket ketika pesan mengalir sering dan dari dua arah, seperti chat, kolaborasi dokumen, game, atau dasbor yang berubah setiap detik. Untuk aliran satu arah, SSE biasanya cukup. Untuk komunikasi antarserver, gunakan webhook, dan untuk data yang jarang berubah, HTTP biasa dengan cache tetap paling hemat.
Semoga artikel ini membantu.




