Belajar WebSocket - Real-Time Collaboration Features
Episode 20 of 34

Belajar WebSocket - Real-Time Collaboration Features

Episode ini membahas fitur kolaborasi real-time: Operational Transformation, CRDT, penyebaran posisi kursor, riwayat versi, serta library seperti Yjs, ShareDB, dan Automerge.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Dua orang mengetik di dokumen yang sama pada saat yang sama. Kalau server hanya menerima "dokumen terbaru menang", satu orang kehilangan seluruh tulisannya. Aplikasi seperti Google Docs memecahkan masalah ini dengan algoritma konflik yang cerdas.

Episode 20 membahas real-time collaboration: bagaimana dua klien mengedit satu dokumen tanpa saling menghapus. Kalian akan belajar dua pendekatan besar — Operational Transformation dan CRDT — serta library yang sudah memecahkan masalah ini agar tidak perlu menulis dari nol.

Masalah Konkurensi

Edit yang Bentrok

Bayangkan dokumen berisi "halo". Klien A menambahkan " dunia" di akhir, klien B menambahkan " sayang" di akhir — keduanya berbasis teks "halo".

Dua edit berbasis versi lama
Versi bersama : "halo"
Edit A        : "halo dunia"
Edit B        : "halo sayang"

Jika server menerapkan A lalu B, dan B dihitung berdasarkan posisi di "halo", hasilnya kacau. Masalah ini disebut konflik: dua operasi valid secara terpisah, tapi tidak kompatibel jika diterapkan begitu saja.

Solusi yang Dibutuhkan

Server perlu cara menggabungkan operasi dari banyak klien sehingga hasil akhir konsisten untuk semua orang. Di sinilah Operational Transformation dan CRDT berperan.

Operational Transformation

Konsep OT

Operational Transformation mengubah posisi operasi agar sesuai dengan operasi lain yang datang lebih dulu.

JSRepresentasi operasi insert
const operasi = {
  tipe: "insert",
  posisi: 5,
  teks: " dunia",
  klien: "user-A",
  urutan: 7,
};

Setiap edit diwakili sebagai operasi: insert, delete, atau retain pada posisi tertentu. Saat dua operasi tumpang tindih, fungsi transform menyesuaikan posisi operasi yang datang belakangan sehingga keduanya bisa diterapkan dalam urutan apa pun.

Implementasi Sederhana

JSTransform posisi saat dua insert
function transform(a, b) {
  if (b.tipe === "insert" && b.posisi <= a.posisi) {
    return { ...a, posisi: a.posisi + b.teks.length };
  }
  if (b.tipe === "delete" && b.posisi < a.posisi) {
    return { ...a, posisi: a.posisi - b.jumlah };
  }
  return a;
}

transform(a, b) menyesuaikan posisi operasi a terhadap b yang sudah diterapkan. OT terbukti andal untuk editor teks, tapi implementasinya rumit — itulah sebabnya sebagian besar tim memakai library yang sudah matang.

CRDT

Konsep CRDT

Conflict-free Replicated Data Types memakai pendekatan berbeda: setiap perubahan membawa identitas unik, dan semua replika mencapai hasil yang sama tanpa server memutuskan siapa menang.

JSElemen CRDT dengan ID unik
const char = {
  id: { klien: "user-A", counter: 42 },
  teks: "x",
  kiri: null,
  kanan: null,
};

Setiap karakter punya ID unik dan posisi relatif terhadap tetangganya. Karena posisi bersifat relatif, dua klien bisa menambahkan karakter di tempat yang sama tanpa saling menimpa — keduanya ada.

Keunggulan CRDT

  • Tanpa server otoritatif: klien bisa mengedit offline lalu menyinkronkan.
  • Konvergensi otomatis: semua replika berakhir dengan hasil sama.
  • Hemat untuk offline-first: cocok untuk aplikasi yang sering terputus jaringan.

Editing Kolaboratif

Kursor dan Seleksi

Selain isi dokumen, kalian menyebarkan posisi kursor agar pengguna lain melihat kursor bergerak real-time.

JSBroadcast posisi kursor
socket.on("cursor:move", (pos) => {
  socket.to("doc:" + pos.docId).emit("cursor:moved", {
    userId: socket.userId,
    posisi: pos.posisi,
    warna: socket.warna,
  });
});

cursor:move disiarkan hanya ke kolaborator dokumen yang sama, bukan ke semua koneksi. Posisi kursor bersifat sementara, jadi tidak perlu disimpan — cukup diteruskan dan ditimpa terus-menerus.

Riwayat dan Conflict Resolution

Dokumen kolaboratif menyimpan riwayat versi. CRDT memudahkan undo karena setiap operasi punya identitas; untuk memutar balik, cukup mengeluarkan operasi yang membatalkannya.

Library Implementasi

Yjs, ShareDB, dan Automerge

Menulis OT atau CRDT dari nol membutuhkan bulanan. Library yang matang sudah menyelesaikan ini.

Install Yjs dan provider
bun add yjs y-websocket

Yjs adalah CRDT paling populer dengan WebSocket provider siap pakai. ShareDB mengimplementasikan OT dan cocok jika kalian butuh JSON document database-style. Automerge fokus pada mode offline-first dengan sinkronisasi.

Integrasi Yjs

JSDokumen Yjs lewat WebSocket
const Y = require("yjs");
const { WebSocketProvider } = require("y-websocket");
 
const doc = new Y.Doc();
const provider = new WebSocketProvider("wss://sync.example.com", "room-1", doc);
 
provider.on("sync", () => {
  console.log("dokumen tersinkronisasi");
});

WebSocketProvider(url, room, doc) menghubungkan dokumen Yjs ke server y-websocket. Semua edit, kursor, dan awareness (siapa yang sedang melihat) dikelola provider secara otomatis.

Penutup

Episode 20 membuka dunia kolaborasi: dari konflik dua edit yang menimpa, menjadi sistem yang mengikat semua orang pada hasil yang sama. OT mengubah operasi agar kompatibel, CRDT membuat semua replika konvergen, dan library siap pakai menyelamatkan kalian dari kompleksitasnya.

Inti yang harus dibawa pulang:

  • Dua edit berbasis versi lama membutuhkan mekanisme resolusi konflik.
  • OT mentransformasi posisi operasi agar bisa diterapkan bersama.
  • CRDT memberi setiap perubahan identitas sehingga hasilnya konvergen.
  • Posisi kursor dan seleksi disiarkan hanya ke kolaborator dokumen.
  • Yjs, ShareDB, dan Automerge menyediakan implementasi yang matang.
  • Yjs punya WebSocket provider sehingga integrasi hanya beberapa baris.

Di episode 21 berikutnya kita membangun real-time notifications system: arsitektur notifikasi, preferensi pengguna, batching, serta persistence status baca dan belum dibaca.

Belajar WebSocket - Real-Time Collaboration Features | Belajar WebSocket