Apa Itu Web Socket? Eksperiment
WebSocket:
Ketika Web Belajar Ngobrol Dua Arah
Eksperimen membangun aplikasi sederhana chat real-time dan apa yang saya pelajari dari prosesnya.
Membuat aplikasi chat sederhana dan belajar tentang WebSocket. Dan saya harus bilang, ini adalah salah satu konsep yang paling mengubah cara saya melihat bagaimana web seharusnya bekerja. Kalau kamu pernah penasaran kenapa aplikasi chat, notifikasi real-time, atau live scoreboard bisa begitu responsive saya akan jelaskan singkat.
Artikel ini bertujuan membangun aplikasi chat real-time menggunakan Node.js dan WebSocket dasar. Semua kode yang ada di sini saya cantumkan dan uji sendiri.
Apa Itu WebSocket, Sebenarnya?
Sebelum membahas WebSocket, kita perlu memahami masalah yang ia selesaikan. HTTP protokol yang selama ini menopang web pada dasarnya bersifat request-response. Seperti mengirim surat, kamu kirim, nunggu balasan, selesai. Contoh seperti sebagian besar kebutuhan web, mengakses halaman, mengambil data, mengirim formulir.
Bayangkan kamu sedang chat. Dengan model HTTP tradisional, ada dua pendekatan yang biasa digunakan:
- Short Polling: Browser nanya ke server setiap kali detik. Boros bandwidth, lambat, dan server kelelahan.
- Long Polling: Browser kirim request dan server tahan koneksi sampai ada data. Lebih baik, tapi server harus tetap terhubung secara real time.
WebSocket solusi untuk masalah ini. Adalah protokol komunikasi yang menyediakan saluran komunikasi full-duplex dua arah melalui satu koneksi TCP. Dengan kata lain, setelah koneksi terbentuk, baik klien maupun server bisa saling kirim pesan kapan saja tanpa perlu membuat koneksi baru setiap kali.
Kita bisa bayangkan kalau HTTP itu seperti intercom, kamu pencet tombol, ngomong, tunggu balasan, selesai. WebSocket itu seperti telepon yang tetap tersambung, begitu terhubung, dua pihak bisa ngobrol bebas kapan saja.
Proses Handshake Dari HTTP ke WebSocket
WebSocket bukan protokol baru yang asing. Ia memanfaatkan infrastruktur HTTP yang sudah ada dengan melakukan sebuah proses bernama WebSocket Handshake, terjadi ketika klien dan server membangun koneksi WebSocket secara asinkron, tidak seperti HTTP Tradisional, yang mengikuti model request-response.
Begini cara kerjanya secara teknis, pertama, klien mengirim HTTP request biasa, tapi dengan header khusus yang meminta upgrade ke protokol WebSocket:
// Request upgrade dari klien (otomatis dari browser)
GET /chat HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
// Respons server jika upgrade disetujui:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
HTTP vs WebSocket, Perbandingan
WebSocket bukan pengganti HTTP. Keduanya punya peran yang berbeda, dan memilih yang tepat tergantung pada kebutuhan spesifik aplikasimu. Ini perbandingan yang saya buat berdasarkan eksperimen:
Aspek | HTTP | WebSocket |
Arah komunikasi | Satu arah (request-response) | Dua arah (full-duplex) |
Koneksi | Dibuka & ditutup per request | Tetap terbuka (persistent) |
Overhead | Tinggi (header ~500 byte/req) | Rendah (frame ~2 byte minimum) |
Latensi | Relatif tinggi | Sangat rendah |
Ideal untuk | Halaman web, REST API, fetch data | Chat, notifikasi, game, live data |
Dukungan browser | Universal | Semua browser modern |
Eksperimen, Membangun Chat Real-Time sederhana
Saya membangun aplikasi chat real-time sederhana menggunakan Node.js dengan library ws (WebSocket native untuk Node), dan front-end HTML/JavaScript murni tanpa framework apapun. Tujuannya adalah memahami mekanisme WebSocket di level paling dasar.
Setup
Petama yang dibutuhkan hanya Node.js dan satu library dengan ketik di gitbash/terminal:
- npm init -y
- npm install
- node server.js
Membuat WebSocket Server (server.js)
Ini adalah jantung dari eksperimen server yang mengelola semua koneksi WebSocket dan meneruskan pesan antar klien:
const WebSocket = require('ws');
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
const html = fs.readFileSync('./index.html', 'utf8');
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(html);
});
const wss = new WebSocket.Server({ server });
const clients = new Map();
wss.on('connection', (ws) => {
const clientId = Date.now();
clients.set(clientId, ws);
console.log(`Klien ${clientId} terhubung. Total: ${clients.size}`);
ws.send(JSON.stringify({
senderId: 'server',
text: `Selamat datang! Kamu adalah pengguna ke-${clients.size}.`,
timestamp: new Date().toLocaleTimeString('id-ID'),
isSelf: false
}));
ws.on('message', (data) => {
const message = JSON.parse(data);
clients.forEach((client, id) => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({
senderId: clientId,
text: message.text,
timestamp: new Date().toLocaleTimeString('id-ID'),
isSelf: id === clientId
}));
}
});
});
ws.on('close', () => {
clients.delete(clientId);
console.log(`Klien ${clientId} terputus. Sisa: ${clients.size}`);
});
});
server.listen(8080, () => {
console.log('Server berjalan di http://localhost:8080');
});
Membuat Klien WebSocket (index.html)
Di sisi klien, WebSocket yang sudah built-in di browser:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Chat sederhana</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Arial, sans-serif; background: #f0f2f5; display: flex; justify-content: center; align-items: center; height: 100vh; }
.chat-box { width: 420px; background: white; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; display: flex; flex-direction: column; height: 560px; }
.header { background: #075E54; color: white; padding: 16px; font-weight: bold; display: flex; justify-content: space-between; align-items: center; }
#status { font-size: 12px; font-weight: normal; opacity: 0.8; }
#messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.msg { max-width: 75%; padding: 8px 12px; border-radius: 10px; font-size: 14px; line-height: 1.4; }
.msg.self { background: #DCF8C6; align-self: flex-end; border-bottom-right-radius: 2px; }
.msg.other { background: #f1f0f0; align-self: flex-start; border-bottom-left-radius: 2px; }
.msg .time { font-size: 11px; color: #999; margin-top: 4px; text-align: right; }
.input-area { padding: 12px; border-top: 1px solid #eee; display: flex; gap: 8px; }
#inputPesan { flex: 1; padding: 10px 14px; border: 1px solid #ddd; border-radius: 24px; outline: none; font-size: 14px; }
button { background: #075E54; color: white; border: none; padding: 10px 18px; border-radius: 24px; cursor: pointer; font-size: 14px; }
button:hover { background: #128C7E; }
</style>
</head>
<body>
<div class="chat-box">
<div class="header">
💬 Chat Sederhana
<span id="status">Menghubungkan...</span>
</div>
<div id="messages"></div>
<div class="input-area">
<input id="inputPesan" type="text" placeholder="Ketik pesan..." onkeydown="if(event.key==='Enter') kirimPesan()" />
<button onclick="kirimPesan()">Kirim</button>
</div>
</div>
<script>
const ws = new WebSocket('ws://localhost:8080');
const messages = document.getElementById('messages');
const status = document.getElementById('status');
ws.onopen = () => { status.textContent = '🟢 Terhubung'; };
ws.onclose = () => { status.textContent = '🔴 Terputus'; };
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const div = document.createElement('div');
div.className = 'msg ' + (data.isSelf ? 'self' : 'other');
div.innerHTML = `${data.text}<div class="time">${data.timestamp}</div>`;
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
};
function kirimPesan() {
const input = document.getElementById('inputPesan');
if (input.value.trim() && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ text: input.value }));
input.value = '';
}
}
</script>
</body>
</html>
Contoh Demo Program
Jalankan di http://localhost:8080/
Hasil Eksperimen dan Temuan Menarik
Menjalankan server dengan node server.js dan membuka tiga tab browser secara bersamaan, saya melakukan beberapa pengujian yang menghasilkan temuan menarik:
- Latensi nyata-nyata rendah: Pesan dari satu tab muncul di tab lain hampir seketika, bahkan dengan koneksi localhost.
- Koneksi persisten benar-benar bekerja: Membuka DevTools Network di browser, dan bisa melihat satu koneksi WebSocket yang tetap terbuka hanya satu entri di tab Network.
- Event-driven sangat bersih: WebSocket di browser sangat intuitif. Empat event handler (onopen, onmessage, onerror, onclose) sudah cukup untuk membangun fungsionalitas penuh.
Catatan: Dalam eksperimen ini menggunakan WebSocket pada level paling dasar.
Kapan Sebaiknya Pakai WebSocket?
Saya bisa menyimpulkan pola penggunaan WebSocket yang paling tepat sasaran membutuhkan aliran data yang terjadi dua arah:
- Aplikasi Chat dan Kolaborasi: Slack, Discord, WhatsApp Web semuanya menggunakan WebSocket atau teknologi serupa untuk pesan real-time.
- Live Dashboard dan Monitoring: Grafik harga saham, monitoring server, analytics real-time semua yang perlu menampilkan data yang berubah setiap detik.
- Game Multiplayer Browser: Sinkronisasi state game antar pemain membutuhkan komunikasi dengan latensi sangat rendah, yang hanya bisa dicapai dengan WebSocket.
- Notifikasi Push Real-Time: Sistem notifikasi di media sosial, platform e-commerce atau sistem manajemen antrian.
- Dokumen Kolaboratif: Google Docs-style collaboration di mana beberapa orang mengedit dokumen yang sama secara bersamaan.
Dan Kapan Sebaiknya Tidak Pakai WebSocket?
Ini juga penting untuk diketahui. WebSocket tidak selalu menjadi jawaban terbaik:
- Untuk halaman web statis atau aplikasi yang sebagian besar kerjanya adalah load halaman dan submit formulir, HTTP REST API jauh lebih sederhana dan cukup.
- Jika data update-nya jarang (misalnya setiap 30 menit), overhead setup WebSocket tidak sepadan. Polling sederhana atau Server-Sent Events (SSE) mungkin lebih cocok.
- Di lingkungan dengan firewall atau proxy ketat, WebSocket bisa bermasalah.
Kelebihan dan Kekurangan
Kelebihan
- Latensi rendah: Begitu koneksi terbentuk, pengiriman pesan hampir tidak ada delay. Ini sangat terasa di aplikasi real-time.
- Efisiensi bandwidth: WebSocket frame jauh lebih kecil dibanding HTTP request dengan semua headernya.
- Dukungan lintas bahasa: Library WebSocket tersedia untuk hampir semua bahasa pemrograman server: Node.js, Python (websockets), Go, Java, Ruby, PHP, dan masih banyak lagi.
Kekurangan
- Kompleksitas server meningkat: Tidak seperti HTTP yang stateless, WebSocket memerlukan server yang bisa mengelola banyak koneksi persisten sekaligus.
- Scaling yang lebih rumit: Di arsitektur multi-server, satu klien yang terhubung ke server A tidak otomatis bisa menerima pesan yang dikirim melalui server B. Diperlukan message broker seperti Redis Pub/Sub untuk mengatasi ini.
- Reconnection harus ditangani manual: Browser tidak secara otomatis reconnect jika koneksi WebSocket terputus.
- Pertimbangan keamanan tambahan: WebSocket rentan terhadap serangan seperti Cross-Site WebSocket Hijacking (CSWSH).
Penutup: Apa yang Saya Pelajari
Eksperimen ini mengubah cara saya melihat web. Selama ini saya selalu berpikir web itu soal halaman yang dimuat, tombol yang diklik, formulir yang dikirim. Tapi dengan WebSocket, web bisa menjadi medium komunikasi yang hidup dan dinamis lebih seperti saluran telepon dari pada kantor pos.
Yang paling berkesan kita bisa mainkan dengan WebSocket. Tidak perlu framework besar, tidak perlu setup yang kompleks hanya Node.js, satu library, dan beberapa puluh baris kode sederhana, kamu sudah punya sistem chat real-time yang fungsional.
Kalau kamu tertarik mencoba sendiri, kode lengkap eksperimen ini bisa kamu jadikan referensi semua kode di artikel ini bisa langsung dijalankan. Selamat bereksperimen!
Referensi
- https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
- https://www.geeksforgeeks.org/javascript/what-is-long-polling-and-short-polling/
- https://en.wikipedia.org/wiki/WebSocket
- https://medium.com/@nile.bits/websocket-handshaking-explained-understanding-the-key-to-real-time-communication-52d631f84c0c
- https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
- https://github.com/websockets/ws
- https://www.altexsoft.com/blog/websockets/
Komentar
Posting Komentar