WebSocket vs Server-Sent Events: Mana yang Terbaik untuk API Real-Time?

Ashley Innocent

Ashley Innocent

13 March 2026

WebSocket vs Server-Sent Events: Mana yang Terbaik untuk API Real-Time?

Intinya

Gunakan Server-Sent Events (SSE) untuk pembaruan satu arah dari server ke klien seperti notifikasi dan umpan langsung. Gunakan WebSocket untuk komunikasi dua arah seperti obrolan dan game. SSE lebih sederhana dan bekerja melalui HTTP. WebSocket lebih kompleks tetapi mendukung pengiriman pesan dua arah. Modern PetstoreAPI mengimplementasikan keduanya untuk kasus penggunaan real-time yang berbeda.

Pendahuluan

Anda memerlukan pembaruan real-time di API Anda. Status hewan peliharaan berubah dari “tersedia” menjadi “diadopsi”—klien perlu segera tahu. Apakah Anda menggunakan WebSocket atau Server-Sent Events (SSE)?

Kebanyakan pengembang secara default memilih WebSocket karena dianggap “lebih canggih.” Namun, SSE seringkali merupakan pilihan yang lebih baik. Ini lebih sederhana, bekerja melalui HTTP standar, dan menangani penyambungan ulang secara otomatis. WebSocket menambah kompleksitas yang mungkin tidak Anda perlukan.

Modern PetstoreAPI mengimplementasikan kedua protokol ini. SSE untuk pembaruan status hewan peliharaan dan notifikasi pesanan. WebSocket untuk penawaran lelang langsung dan obrolan real-time. Setiap protokol melayani kasus penggunaan yang berbeda.

💡
Jika Anda membangun atau menguji API real-time, Apidog mendukung pengujian SSE dan WebSocket. Anda dapat menguji aliran event, memvalidasi format pesan, dan mensimulasikan skenario penyambungan ulang.
tombol

Dalam panduan ini, Anda akan mempelajari perbedaan antara SSE dan WebSocket, melihat contoh nyata dari Modern PetstoreAPI, dan menemukan kapan harus menggunakan setiap protokol.

Apa Itu Server-Sent Events (SSE)?

SSE adalah protokol berbasis HTTP untuk mengalirkan event dari server ke klien.

Cara Kerja SSE

Klien membuka koneksi dan menerima event saat terjadi:

const eventSource = new EventSource('https://petstoreapi.com/v1/pets/notifications');

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Pet update:', data);
};

eventSource.addEventListener('adoption', (event) => {
  const data = JSON.parse(event.data);
  console.log('Pet adopted:', data.petId);
});

Server mengirimkan event:

GET /v1/pets/notifications
Accept: text/event-stream

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache

event: adoption
data: {"petId":"019b4132","userId":"user-456"}

event: status-change
data: {"petId":"019b4127","status":"AVAILABLE"}

Fitur SSE

1. Komunikasi satu arah

Server mengirim ke klien. Klien tidak dapat mengirim pesan kembali melalui koneksi SSE (tetapi dapat menggunakan permintaan HTTP biasa).

2. Dibangun di atas HTTP

Menggunakan HTTP standar. Bekerja melalui proxy, firewall, dan CDN.

3. Penyambungan ulang otomatis

Jika koneksi terputus, browser akan menyambungkan ulang secara otomatis.

4. ID Event untuk melanjutkan

Server dapat mengirim ID event. Klien melanjutkan dari event terakhir yang diterima:

id: 123
event: adoption
data: {"petId":"019b4132"}

id: 124
event: status-change
data: {"petId":"019b4127"}

Jika terputus, klien mengirim header Last-Event-ID: 124 untuk melanjutkan.

5. Protokol sederhana

Format berbasis teks. Mudah di-debug dengan curl:

curl -N -H "Accept: text/event-stream" \
  https://petstoreapi.com/v1/pets/notifications

Keterbatasan SSE

1. Hanya satu arah

Klien tidak dapat mengirim pesan melalui SSE. Memerlukan permintaan HTTP terpisah untuk komunikasi klien-ke-server.

2. Hanya teks

SSE mengirim teks. Data biner harus dienkode base64.

3. Batasan koneksi browser

Browser membatasi koneksi SSE per domain (biasanya 6). Ini bukan masalah untuk sebagian besar aplikasi.

4. Tidak ada kompresi bawaan

Kompresi HTTP berfungsi, tetapi tidak ada kompresi tingkat protokol seperti WebSocket.

Apa Itu WebSocket?

WebSocket adalah protokol dua arah full-duplex melalui koneksi persisten.

Cara Kerja WebSocket

Klien dan server sama-sama dapat mengirim pesan kapan saja:

const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');

// Send message to server
ws.send(JSON.stringify({
  type: 'bid',
  amount: 500
}));

// Receive messages from server
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Auction update:', data);
};

ws.onclose = () => {
  console.log('Connection closed');
  // Manual reconnection logic needed
};

Server dapat mengirim kapan saja:

{"type":"bid","userId":"user-456","amount":550}
{"type":"outbid","newAmount":550}

Klien dapat mengirim kapan saja:

{"type":"bid","amount":600}
{"type":"watch","petId":"019b4132"}

Fitur WebSocket

1. Dua Arah

Klien dan server sama-sama dapat mengirim pesan kapan saja. Komunikasi dua arah yang sesungguhnya.

2. Latensi Rendah

Koneksi persisten. Tidak ada overhead HTTP per pesan. Ideal untuk gaming, obrolan, kolaborasi langsung.

3. Dukungan Biner

Dapat mengirim data biner secara langsung. Tidak perlu enkripsi base64.

4. Protokol Kustom

Menggunakan ws:// atau wss:// (aman). Bukan HTTP setelah handshake awal.

5. Berbasis Frame

Pesan dibingkai. Dapat mengirim pesan parsial dan menyatukannya kembali.

Keterbatasan WebSocket

1. Penyiapan yang kompleks

Membutuhkan server WebSocket. Lebih kompleks daripada endpoint HTTP.

2. Penyambungan ulang manual

Tidak ada penyambungan ulang otomatis. Anda harus mengimplementasikan logika coba lagi.

3. Masalah proxy

Beberapa proxy korporat memblokir WebSocket. Proxy HTTP tidak memahami ws://.

4. Stateful (Berstate)

Server harus melacak koneksi. Lebih sulit diskalakan daripada HTTP tanpa state.

5. Tanpa fitur HTTP

Tidak dapat menggunakan caching HTTP, kode status, atau header standar setelah handshake.

Perbandingan Berdampingan

Fitur SSE WebSocket
Arah Server → Klien Dua Arah
Protokol HTTP Kustom (ws://)
Penyambungan Ulang Otomatis Manual
Dukungan Browser Semua modern Semua modern
Ramah Proxy Ya Terkadang
Kompleksitas Sederhana Kompleks
Data Biner Tidak (hanya teks) Ya
Latensi Rendah Sangat Rendah
Skalabilitas Tinggi (tanpa state) Sedang (berstate)
Kasus Penggunaan Notifikasi, umpan Obrolan, game, kolaborasi

Bagaimana Modern PetstoreAPI Menggunakan Keduanya

Modern PetstoreAPI mengimplementasikan SSE dan WebSocket untuk skenario yang berbeda.

SSE untuk Pembaruan Hewan Peliharaan

Endpoint: GET /v1/pets/notifications

const events = new EventSource(
  'https://petstoreapi.com/v1/pets/notifications?userId=user-456'
);

events.addEventListener('adoption', (e) => {
  const data = JSON.parse(e.data);
  showNotification(`${data.petName} was adopted!`);
});

events.addEventListener('status-change', (e) => {
  const data = JSON.parse(e.data);
  updatePetStatus(data.petId, data.status);
});

Implementasi server:

app.get('/v1/pets/notifications', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const userId = req.query.userId;

  // Subscribe to pet updates
  const subscription = petUpdates.subscribe(userId, (event) => {
    res.write(`event: ${event.type}\n`);
    res.write(`data: ${JSON.stringify(event.data)}\n\n`);
  });

  req.on('close', () => {
    subscription.unsubscribe();
  });
});

Kasus penggunaan:

WebSocket untuk Lelang Langsung

Endpoint: wss://petstoreapi.com/auctions/{auctionId}

const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');

// Place bid
function placeBid(amount) {
  ws.send(JSON.stringify({
    type: 'bid',
    amount
  }));
}

// Receive updates
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  switch (msg.type) {
    case 'bid':
      updateCurrentBid(msg.amount, msg.userId);
      break;
    case 'outbid':
      showOutbidNotification(msg.newAmount);
      break;
    case 'auction-end':
      showAuctionResult(msg.winner);
      break;
  }
};

Implementasi server:

wss.on('connection', (ws, req) => {
  const auctionId = req.params.auctionId;
  const auction = auctions.get(auctionId);

  ws.on('message', (data) => {
    const msg = JSON.parse(data);

    if (msg.type === 'bid') {
      const result = auction.placeBid(msg.userId, msg.amount);

      // Broadcast to all participants
      auction.participants.forEach(participant => {
        participant.send(JSON.stringify({
          type: 'bid',
          userId: msg.userId,
          amount: msg.amount
        }));
      });
    }
  });
});

Kasus penggunaan:

Menguji API Real-Time dengan Apidog

Apidog mendukung pengujian API SSE dan WebSocket.

Menguji SSE

1. Buat permintaan SSE:

GET https://petstoreapi.com/v1/pets/notifications
Accept: text/event-stream

2. Validasi event:

3. Skenario pengujian:

Menguji WebSocket

1. Buat koneksi WebSocket:

wss://petstoreapi.com/auctions/019b4132

2. Kirim pesan pengujian:

{"type":"bid","amount":500}
{"type":"watch","petId":"019b4132"}

3. Validasi respons:

4. Skenario pengujian:

Kapan Menggunakan Masing-masing

Gunakan SSE Ketika:

Contoh:

Gunakan WebSocket Ketika:

Contoh:

Jangan Gunakan WebSocket Hanya Karena:

❌ “Ini lebih canggih” - Kompleksitas tanpa manfaat

❌ “Semua orang menggunakannya” - SSE seringkali lebih sederhana

❌ “Ini lebih cepat” - SSE cukup cepat untuk sebagian besar kasus penggunaan

❌ “Ini dua arah” - Apakah Anda benar-benar membutuhkan dua arah?

Kesimpulan

SSE dan WebSocket sama-sama memungkinkan komunikasi real-time, tetapi dirancang untuk skenario yang berbeda. SSE unggul dalam pembaruan satu arah dari server ke klien dengan penyambungan ulang otomatis dan kompatibilitas HTTP. WebSocket menonjol untuk komunikasi dua arah dengan latensi rendah.

Modern PetstoreAPI menunjukkan cara menggunakan kedua protokol ini secara efektif. SSE untuk notifikasi dan pembaruan status. WebSocket untuk lelang langsung dan obrolan. Pilihlah berdasarkan kasus penggunaan Anda, bukan protokol mana yang terlihat “lebih baik.”

Uji API real-time Anda dengan Apidog untuk memastikan implementasi SSE dan WebSocket berfungsi dengan benar di berbagai skenario.

FAQ

Bisakah SSE bekerja melalui firewall perusahaan?

Ya. SSE menggunakan HTTP standar, sehingga berfungsi melalui proxy HTTP dan firewall. WebSocket menggunakan protokol kustom yang diblokir oleh beberapa proxy.

Apakah WebSocket lebih cepat dari SSE?

WebSocket memiliki latensi sedikit lebih rendah (tidak ada overhead HTTP per pesan), tetapi untuk sebagian besar aplikasi, perbedaannya dapat diabaikan. SSE cukup cepat untuk notifikasi, umpan, dan pembaruan status.

Bagaimana Anda menangani penyambungan ulang SSE?

Browser menangani penyambungan ulang secara otomatis. Kirim ID event dari server, dan klien akan melanjutkan dari event terakhir yang diterima menggunakan header Last-Event-ID.

Bisakah Anda menggunakan SSE dengan aplikasi seluler?

Ya. iOS dan Android mendukung SSE melalui klien HTTP atau pustaka native. SSE bekerja di mana pun HTTP bekerja.

Berapa waktu koneksi SSE maksimum?

Tidak ada batasan waktu yang ketat. Koneksi SSE dapat tetap terbuka tanpa batas waktu. Beberapa proxy atau penyeimbang beban mungkin memiliki batas waktu (biasanya 30-60 detik), tetapi browser akan menyambungkan ulang secara otomatis.

Bisakah WebSocket mengirim data biner?

Ya. WebSocket mendukung frame teks dan biner. Anda dapat mengirim gambar, audio, atau data biner apa pun tanpa enkripsi base64.

Berapa banyak koneksi SSE yang dapat dimiliki browser?

Browser membatasi koneksi SSE per domain (biasanya 6). Ini jarang menjadi masalah—sebagian besar aplikasi hanya memerlukan 1-2 koneksi SSE.

Apakah Anda memerlukan server khusus untuk SSE?

Tidak. Server HTTP mana pun dapat menangani SSE. Cukup atur header yang benar (Content-Type: text/event-stream) dan biarkan koneksi tetap terbuka.

Mengembangkan API dengan Apidog

Apidog adalah alat pengembangan API yang membantu Anda mengembangkan API dengan lebih mudah dan efisien.

WebSocket vs Server-Sent Events: Mana yang Terbaik untuk API Real-Time?