Server-Sent Events (SSE) qua EventSource và WebSocket đều cho phép server đẩy dữ liệu đến client realtime, nhưng có khác biệt căn bản.
So sánh chi tiết
| Tiêu chí | EventSource (SSE) | WebSocket |
|---|---|---|
| Giao thức | HTTP/HTTPS (text/event-stream) | WebSocket Protocol (ws://, wss://) |
| Chiều truyền | Một chiều: Server → Client | Hai chiều: Full-duplex |
| Client gửi data | Không (phải dùng HTTP request riêng) | Có (send() bất kỳ lúc nào) |
| Auto-reconnect | Tự động (built-in) | Phải tự implement |
| Connection limit | 6 connections/hostname (HTTP/1.1), không giới hạn HTTP/2 | 1 connection/origin (thường), không giới hạn HTTP/2 |
| Binary data | Không (chỉ text/UTF-8) | Có (ArrayBuffer, Blob) |
| Custom Event Types | Có (event: name trong stream) | Phải tự định nghĩa protocol |
| Headers/Authentication | Cookie, Authorization header tự động | Handshake HTTP upgrade, sau đó tự quản lý |
| Proxy/Firewall friendly | Rất tốt (chạy trên HTTP chuẩn) | Có thể bị chặn (upgrade request) |
| Browser Support | Tất cả modern (IE: không, Edge: có) | Tất cả modern (IE10+) |
Server-Sent Events Format
data: {"message": "Hello", "time": 1234567890}\n\n
event: notification
data: {"title": "New order", "id": 42}\n\n
: This is a comment line\n\n
retry: 5000\n\n
Client Code - EventSource
var evtSource = new EventSource('/events');
evtSource.onopen = function() { console.log('Kết nối SSE mở'); };
evtSource.onmessage = function(e) {
console.log('Message:', e.data); // Mặc định event type = 'message'
};
evtSource.addEventListener('notification', function(e) {
var data = JSON.parse(e.data);
showNotification(data.title);
});
evtSource.onerror = function(err) {
console.error('SSE error:', err);
// Tự động reconnect sau ~2-3s
};
Server Code (Node.js/Express)
app.get('/events', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();
// Gửi comment để keep-alive
const interval = setInterval(() => {
res.write(':keepalive\n\n');
}, 15000);
// Gửi data
const send = (event, data) => {
res.write(`event: ${event}\n`);
res.write(`data: ${JSON.stringify(data)}\n\n`);
};
// Ví dụ: gửi mỗi 5s
const dataInterval = setInterval(() => {
send('message', { time: Date.now(), value: Math.random() });
}, 5000);
req.on('close', () => {
clearInterval(interval);
clearInterval(dataInterval);
});
});
Khi nào dùng cái nào?
- Dùng SSE (EventSource) khi: Chỉ cần server push (live feed, notification, stock ticker, log streaming), muốn đơn giản, auto-reconnect, HTTP/2 multiplexing.
- Dùng WebSocket khi: Cần hai chiều (chat, game multiplayer, collaborative editing), binary data, latency cực thấp, custom protocol.
Polyfill SSE cho IE
<script src="https://cdn.jsdelivr.net/npm/event-source-polyfill@1.0.31/src/eventsource.min.js"></script>