Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> HTML

EventSource (SSE) vs WebSocket trong HTML5 Server-Sent Events

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>