SSE (Server-Sent Events) — standar W3C yang memungkinkan server mengirim data streaming ke klien melalui satu koneksi HTTP dalam mode satu arah. Tidak seperti WebSocket, SSE bekerja di atas HTTP biasa dan tidak memerlukan protokol khusus atau pustaka di sisi klien. Menurut spesifikasi W3C HTML Living Standard (2025), EventSource API didukung di semua browser modern, termasuk Chrome, Firefox, Safari, dan Edge.
Poin Utama
SSE (Server-Sent Events) — teknologi yang memungkinkan server web mengirim data ke klien kapan saja setelah koneksi dibuat. Ini distandarisasi oleh WHATWG sebagai bagian dari HTML Living Standard dan menggunakan tipe MIME text/event-stream. SSE mendukung transmisi data teks dengan kemampuan untuk menentukan ID pesan, tipe peristiwa, dan penundaan koneksi ulang.
Tidak seperti WebSocket, yang memerlukan protokol dua arah dan permintaan upgrade, SSE bekerja di atas HTTP biasa. Server mengatur header Content-Type: text/event-stream, mengirim data dalam potongan-potongan, dan menjaga koneksi tetap terbuka. Klien menerima data melalui EventSource API browser, yang secara otomatis mem-parsing streaming dan menghasilkan peristiwa.
Menurut data CanIUse (2025), EventSource API didukung di 97,5% browser secara global. Tidak didukung di Internet Explorer dan beberapa browser seluler (Samsung Internet hingga versi 7.0). Untuk kasus ini ada polyfill yang meniru EventSource melalui XHR streaming. SSE tidak bekerja dengan HTTP/1.1 pipelining, tetapi sepenuhnya kompatibel dengan HTTP/2 server push.
SSE diusulkan sebagai bagian dari spesifikasi HTML5 pada tahun 2009 dengan nama Server-Sent DOM Events. Implementasi pertama muncul di Opera 9.0, kemudian di Firefox 6.0 (2011), Chrome 9.0 (2011), dan Safari 5.0 (2010). Pada tahun 2015, spesifikasi dipisahkan menjadi bagian terpisah dari HTML Living Standard. Meskipun memiliki sejarah satu dekade, SSE tetap kurang populer dibandingkan WebSocket karena sifatnya yang satu arah.
Mekanisme kerja SSE sebagai berikut: klien membuat instance EventSource dengan URL endpoint server. Browser mengirim permintaan GET dengan header Accept: text/event-stream. Server merespons dengan status 200 OK dan header Content-Type: text/event-stream, setelah itu mulai mengirim data dalam format event-stream. Koneksi tetap terbuka sampai server mengirim sinyal terminasi atau klien memanggil close().
Di sisi server, data dikirim dalam potongan (chunked transfer encoding). Setiap blok data adalah pesan teks yang terdiri dari baris bidang (event, data, id, retry). Server dapat mengirim pesan kapan saja, menjadikan SSE ideal untuk notifikasi dan pembaruan status. Koneksi tidak memerlukan pertukaran paket heartbeat yang konstan (seperti WebSocket), meskipun bidang retry mengontrol frekuensi koneksi ulang.
Menurut data pengujian kinerja (2024), SSE menyediakan throughput hingga 10.000 pesan per detik per koneksi dengan ukuran pesan 256 byte. Di sisi server, setiap koneksi SSE mengonsumsi sekitar 5–10 KB memori, memungkinkan satu server mendukung 50.000+ koneksi simultan dengan RAM 1 GB. Ini jauh lebih sedikit daripada WebSocket karena tidak adanya protokol biner.
Format text/event-stream — protokol teks sederhana di mana setiap pesan terdiri dari bidang bernama yang dipisahkan oleh karakter baris baru. Setiap bidang memiliki format “NamaBidang: nilai”. Pesan dipisahkan oleh dua karakter baris baru ( ).
Bidang yang didukung: event (tipe peristiwa, default message), data (string data, bisa multi-baris), id (ID peristiwa terakhir, disimpan di Last-Event-ID), retry (waktu koneksi ulang dalam milidetik). Komentar dimulai dengan titik dua (:) dan diabaikan oleh parser, tetapi dapat digunakan untuk heartbeat.
| Bidang | Wajib | Tujuan |
|---|---|---|
| event | Tidak | Tipe peristiwa (default message) |
| data | Ya | String data pesan |
| id | Tidak | ID peristiwa untuk Last-Event-ID |
| retry | Tidak | Penundaan koneksi ulang dalam ms |
: heartbeat comment
event: update
data: {"user": "Alice", "action": "typing"}
id: 1001
event: notification
data: {"type": "info", "text": "New version available"}
data: {"type": "action", "url": "/upgrade"}
retry: 3000
event: close
data: Session ended
EventSource API — antarmuka browser bawaan untuk menerima SSE. Untuk membuat koneksi, cukup panggil konstruktor dengan URL endpoint. EventSource secara otomatis membuat koneksi, menangani koneksi ulang, dan mem-parsing pesan masuk menjadi peristiwa JavaScript.
Peristiwa EventSource: open (koneksi dibuat), message (pesan diterima tanpa menentukan event), error (kesalahan koneksi). Untuk peristiwa kustom (event: custom) dapat menggunakan addEventListener dengan nama peristiwa. EventSource secara otomatis mengirim header Last-Event-ID saat koneksi ulang, memungkinkan server melanjutkan streaming dari titik yang terputus.
Menurut dokumentasi MDN (2025), EventSource mendukung CORS dan pengiriman kredensial (withCredentials). Untuk mengirim header kustom atau body permintaan, EventSource tidak cocok — diperlukan implementasi manual melalui fetch + ReadableStream. EventSource tidak mendukung data biner — hanya teks dan JSON.
const eventSource = new EventSource('/api/events/stream');
eventSource.addEventListener('open', () => {
console.log('Koneksi SSE dibuka');
});
eventSource.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log('Diterima:', data);
renderUpdate(data);
});
eventSource.addEventListener('notification', (event) => {
const notification = JSON.parse(event.data);
showNotification(notification.text);
});
eventSource.addEventListener('error', (error) => {
console.error('Kesalahan SSE:', error);
// Koneksi ulang otomatis browser
});
// Tutup koneksi
eventSource.close();
SSE dan WebSocket — teknologi berbeda untuk komunikasi real-time, masing-masing dengan keunggulannya sendiri. WebSocket cocok untuk pertukaran data dua arah (obrolan, game, pengeditan bersama), SSE untuk aliran satu arah dari server ke klien (notifikasi, umpan berita, ticker).
Perbedaan utama — WebSocket memerlukan permintaan upgrade dari HTTP/1.1 ke protokol WebSocket (ws://), yang dapat diblokir oleh proxy perusahaan. SSE bekerja di atas HTTP biasa, melewati semua proxy, dan tidak memerlukan konfigurasi server khusus. SSE juga lebih sederhana dalam implementasi — server tidak memerlukan pustaka tambahan, cukup format respons HTTP dengan benar.
Menurut data pengujian komparatif (2024), pada satu proses server, SSE mendukung 30–50% lebih banyak koneksi daripada WebSocket karena protokol yang lebih sederhana. Namun, latensi SSE lebih tinggi (50–200 ms vs 10–50 ms untuk WebSocket) karena SSE menggunakan chunked HTTP, bukan aliran dua arah penuh dengan frame biner.
| Karakteristik | SSE | WebSocket |
|---|---|---|
| Arah | Server → klien | Dua arah |
| Protokol | HTTP (text/event-stream) | ws:// / wss:// (RFC 6455) |
| Browser | 97,5% (EventSource bawaan) | 97% (WebSocket bawaan) |
| Data | Hanya teks / JSON | Teks + biner (Blob, ArrayBuffer) |
| Penanganan proxy | Melewati semua proxy | Memerlukan konfigurasi proxy |
| Koneksi ulang | Otomatis (browser) | Implementasi manual |
| Riwayat | Last-Event-ID | Tanpa riwayat bawaan |
Implementasi SSE di server tidak memerlukan pustaka — cukup atur header HTTP yang benar dan kirim data dalam format text/event-stream. Mari kita lihat contoh di Node.js menggunakan modul http bawaan. Server mengatur header Content-Type dan Cache-Control, lalu mengirim pesan setiap N detik.
Menurut MDN Web Docs (2025), header wajib untuk SSE adalah: Content-Type: text/event-stream, Cache-Control: no-cache, dan Connection: keep-alive. Tanpa Cache-Control, browser dapat menyimpan cache aliran SSE, yang akan menghentikan pengiriman. Connection: keep-alive secara eksplisit memberi tahu browser untuk menjaga koneksi tetap terbuka.
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
let eventId = 0;
const interval = setInterval(() => {
eventId++;
res.write(`id: ${eventId}\n`);
res.write(`event: update\n`);
res.write(`data: {"waktu": "${new Date().toISOString()}", "id":${eventId}}\n\n`);
}, 2000);
req.on('close', () => {
clearInterval(interval);
});
}).listen(3000);
from flask import Response, Flask
import time
import json
app = Flask(__name__)
@app.route('/stream')
def stream():
def generate():
event_id = 0
while True:
event_id += 1
data = json.dumps(
{'ticker': 'AAPL', 'price': 150.25})
yield f'id: {event_id}\nevent: price\ndata: {data}\n\n'
time.sleep(1)
return Response(generate(),
mimetype='text/event-stream')
Penggunaan SSE di aplikasi seluler dibatasi oleh tidak adanya implementasi asli EventSource untuk iOS dan Android. Di platform seluler, SSE diimplementasikan melalui pustaka pihak ketiga: di iOS — melalui URLSession dengan NSURLProtocol, di Android — melalui OkHttp dengan dukungan SSE (okhttp-sse). Untuk React Native dan Flutter, tersedia paket yang meniru EventSource.
Di iOS implementasi asli SSE dimungkinkan melalui URLSessionDataDelegate. Saat menerima data di metode urlSession(_:dataTask:didReceive:), aplikasi mengumpulkan buffer dan mem-parsing format event-stream secara manual. Menurut blog pengembangan iOS (2024), konsumsi baterai pada SSE di iOS 40% lebih rendah dibandingkan koneksi WebSocket konstan, karena tidak adanya paket heartbeat.
Di Android OkHttp menyediakan kelas EventSource.Factory untuk berlangganan aliran SSE. Aplikasi Android dapat menggunakan SSE untuk notifikasi ketika FCM tidak tersedia atau untuk sinkronisasi data di latar belakang. SSE di Android bekerja dengan baik dengan WorkManager untuk tugas latar belakang jangka panjang. Menurut dokumentasi OkHttp (2025), okhttp-sse mendukung koneksi ulang otomatis dengan listener kustom.
Pertanyaan yang Sering Diajukan
SSE — transmisi satu arah (server → klien) melalui HTTP, tidak memerlukan pustaka di sisi klien. WebSocket — transmisi dua arah dengan protokol biner. SSE lebih sederhana dalam implementasi, WebSocket cocok untuk tugas di mana klien juga mengirim data.
Tidak, SSE hanya mentransmisikan data teks. Untuk data biner (gambar, audio) diperlukan pengkodean Base64, yang meningkatkan ukuran sebesar 33%. Untuk aliran biner, lebih baik menggunakan WebSocket.
EventSource secara otomatis terhubung kembali saat putus. Waktu penundaan diatur oleh bidang retry di aliran (default 1000 ms). Saat koneksi ulang, browser mengirim header Last-Event-ID, memungkinkan server melanjutkan streaming dari titik yang terputus.
Setiap browser memiliki batasan jumlah koneksi HTTP simultan dengan satu domain. Untuk HTTP/1.1 — 6–8 koneksi per domain, untuk HTTP/2 — hingga 100. SSE menggunakan satu koneksi, sehingga tidak ada persaingan dengan permintaan lain.
SSE hanya cocok untuk menerima pesan (masuk). Untuk mengirim pesan (keluar) diperlukan permintaan HTTP terpisah (POST). Untuk obrolan lengkap, lebih nyaman menggunakan WebSocket atau Socket.IO dengan komunikasi dua arah dalam satu koneksi.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga