Episode ini membahas kegagalan koneksi: jenis-jenis error, pola penanganan yang benar, strategi reconnection dengan exponential backoff, konfigurasi bawaan Socket.IO, serta pemulihan state dan pesan yang hilang.

Jaringan tidak pernah sempurna. WiFi terputus, server restart, VPN gagal, atau handphone berpindah jaringan — semua itu memutus koneksi WebSocket. Aplikasi yang baik tidak menyerah saat koneksi putus; ia mencoba kembali dengan cerdas dan memulihkan keadaan.
Episode 12 membahas error handling: mengenali dan menangani berbagai kegagalan, serta reconnection strategies: mencoba kembali dengan exponential backoff, membatasi percobaan, dan memastikan tidak ada data yang hilang.
Kegagalan koneksi datang dari berbagai sumber dengan karakter berbeda. Kegagalan umum yang akan kalian temui:
Setiap jenis error butuh respons berbeda: retry untuk network failure, menunggu untuk server unavailable, dan memberi tahu pengguna untuk auth failure.
Browser menyediakan event khusus untuk setiap fase koneksi.
const ws = new WebSocket("wss://api.example.com/ws");
ws.onerror = (event) => {
console.error("error WebSocket:", event.message);
};
ws.onclose = (event) => {
console.log("koneksi ditutup:", event.code, event.reason);
if (event.code !== 1000) {
cobaKoneksiKembali();
}
};Event onerror memberi tahu terjadinya masalah, dan onclose membawa kode penutup. Kode 1000 berarti penutupan normal; kode lain seperti 1006 (abnormal) menandakan koneksi putus dan perlu dicoba kembali.
Server juga harus menangani kesalahan dengan tenang, tanpa crash.
wss.on("connection", (ws) => {
ws.on("error", (err) => {
console.error("error koneksi:", err.message);
});
ws.on("message", (data) => {
try {
prosesPesan(data);
} catch (err) {
ws.send(JSON.stringify({ error: err.message }));
}
});
});Setiap koneksi punya handler error sendiri. Pemrosesan pesan dibungkus try-catch agar satu pesan rusak tidak menghentikan seluruh proses.
Mencoba kembali langsung berulang-ulang akan membebani server saat sedang bermasalah. Solusinya adalah menambah jeda secara eksponensial.
let percobaan = 0;
const MAKS_PERCOBAAN = 5;
function hubungkan() {
const jeda = Math.min(1000 * 2 ** percobaan, 30000);
setTimeout(() => {
const ws = new WebSocket("wss://api.example.com/ws");
ws.onopen = () => {
percobaan = 0;
};
ws.onclose = () => {
percobaan += 1;
if (percobaan <= MAKS_PEROBAAN) {
hubungkan();
}
};
}, jeda);
}Math.min(1000 * 2 ** percobaan, 30000) menghasilkan jeda 1, 2, 4 detik hingga dibatasi maksimal 30 detik. Setiap koneksi berhasil mereset penghitung, sehingga restart server tidak menghancurkan klien.
Reconnect tanpa batas bisa berlangsung selamanya. Batasi jumlah percobaan dan tampilkan pesan yang jujur saat menyerah: setelah lima percobaan gagal, tampilkan pilihan untuk muat ulang halaman. Pengguna lebih sabar jika diberi tahu keadaan daripada menunggu diam-diam.
Socket.IO punya reconnection otomatis yang bisa diatur dengan beberapa opsi.
const socket = io("https://api.example.com", {
reconnection: true,
reconnectionAttempts: 10,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
});
socket.on("reconnect_attempt", (attempt) => {
console.log("percobaan ke:", attempt);
});
socket.on("reconnect_failed", () => {
console.log("semua percobaan gagal");
});reconnection: true mengaktifkan reconnect otomatis, reconnectionDelayMax membatasi jeda maksimum. Event reconnect_attempt dan reconnect_failed memberi kalian visibilitas proses.
Untuk kontrol penuh, matikan reconnection bawaan dan kelola sendiri.
const socket = io("https://api.example.com", {
reconnection: false,
});reconnection: false mematikan otomatisasi, dan socket.connect() memicu sambungan ulang secara manual. Mode ini berguna saat menggabungkan reconnection dengan logika bisnis tertentu.
Saat koneksi pulih, klien harus menyinkronkan kembali kondisinya dengan server.
socket.on("connect", () => {
socket.emit("sync:request", { dariId: idPesanTerakhir });
socket.emit("presence:set", { status: "online" });
socket.emit("room:rejoin", daftarRoom);
});idPesanTerakhir memungkinkan server mengirim ulang pesan yang terlewat. Bergabung kembali ke room dan mengatur ulang presence memastikan klien kembali ke posisi yang benar setelah reconnect.
Episode 12 mengubah kegagalan jaringan dari bencana menjadi kejadian yang tertangani: error dikenali, reconnect dilakukan dengan jeda yang makin lama, dan state dipulihkan setelah koneksi kembali.
Inti yang harus dibawa pulang:
Di episode 13 berikutnya kita membahas rate limiting & throttling: algoritma token bucket dan sliding window, pembatasan per pengguna, serta cara menangani backpressure di klien dan server.