🔹 Giới thiệu
Bạn có bao giờ muốn cập nhật giao diện người dùng của mình theo thời gian thực mà không cần đến WebSockets phức tạp hoặc cơ chế polling tốn kém? Đó chính là lúc Sự kiện máy chủ gửi (SSE) phát huy tác dụng.
SSE là một cơ chế đơn giản cho phép máy chủ gửi dữ liệu đến khách hàng thông qua một kết nối HTTP duy trì lâu dài duy nhất. Nó nhẹ, đáng tin cậy và đã được tích hợp sẵn trong các trình duyệt thông qua API EventSource.
🔹 Tại sao nên sử dụng SSE?
Dưới đây là những lý do khiến SSE trở nên tuyệt vời:
✅ Đơn giản – chỉ là HTTP tiêu chuẩn, không cần giao thức đặc biệt.
✅ Truyền tải một chiều – hoàn hảo khi chỉ cần giao tiếp từ máy chủ → khách hàng.
✅ Tự động kết nối lại – được trình duyệt xử lý.
✅ Tối ưu tài nguyên – không cần gửi yêu cầu polling lặp lại.
✅ Thân thiện với tường lửa – hoạt động qua HTTP/HTTPS tiêu chuẩn.
Một số trường hợp sử dụng:
- Cập nhật giá cổ phiếu 📈
- Thông báo 🔔
- Bảng điều khiển trực tiếp 📊
- Tin nhắn chat 💬
- Ghi lại nhật ký 🖥️
🔹 Cách hoạt động của SSE
Quy trình hoạt động rất đơn giản:
- Khách hàng mở một kết nối sử dụng
EventSource. - Máy chủ phản hồi với
Content-Type: text/event-stream. - Máy chủ gửi các thông điệp theo định dạng đặc biệt.
- Trình duyệt chuyển tiếp các sự kiện đến ứng dụng JavaScript của bạn.
Khách hàng (EventSource) <--- Luồng HTTP ---> Máy chủ
🔹 Ví dụ cơ bản
🖥️ Máy chủ (Node.js + Express)
import express from "express";
const app = express();
app.get("/events", (req, res) => {
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
let count = 0;
// Gửi một thông điệp mỗi 2 giây
const interval = setInterval(() => {
res.write(`data: Xin chào ${count++} tại ${new Date().toISOString()}\n\n`);
}, 2000);
// Nếu khách hàng đóng kết nối, dừng gửi
req.on("close", () => {
clearInterval(interval);
});
});
app.listen(3000, () => console.log("Máy chủ SSE đang chạy tại http://localhost:3000"));
💻 Khách hàng (Ví dụ với React)
import { useEffect, useState } from "react";
export default function Notifications() {
const [messages, setMessages] = useState([]);
useEffect(() => {
const eventSource = new EventSource("http://localhost:3000/events");
eventSource.onmessage = (event) => {
setMessages((prev) => [...prev, event.data]);
};
eventSource.onerror = (err) => {
console.error("Lỗi SSE:", err);
eventSource.close();
};
return () => {
eventSource.close(); // dọn dẹp
};
}, []); // ✅ chỉ chạy một lần
return (
<div>
<h2>🔔 Thông báo</h2>
<ul>
{messages.map((msg, i) => (
<li key={i}>{msg}</li>
))}
</ul>
</div>
);
}
🔹 Gửi sự kiện tùy chỉnh
SSE không chỉ giới hạn ở các sự kiện message. Bạn có thể gửi các loại sự kiện tùy chỉnh:
Máy chủ:
event: priceUpdate
data: 123.45
Khách hàng:
eventSource.addEventListener("priceUpdate", (e) => {
console.log("Cập nhật giá:", e.data);
});
🔹 Xử lý lỗi & Kết nối lại
- Mặc định,
EventSourcetự động kết nối lại nếu kết nối bị ngắt. - Bạn có thể kiểm soát khoảng thời gian thử lại bằng cách gửi:
retry: 5000
Điều này thông báo cho khách hàng kết nối lại sau 5 giây.
- Luôn xử lý lỗi một cách ân cần trong
onerror.
🔹 SSE so với WebSockets và Polling
| Tính năng | Polling 🔄 | SSE 📡 | WebSockets 🔀 |
|---|---|---|---|
| Hướng | Khách hàng → Máy chủ chỉ | Máy chủ → Khách hàng chỉ | Hai chiều |
| Độ phức tạp | Thấp | Trung bình | Cao |
| Tài nguyên | Cao | Thấp | Trung bình |
| Hỗ trợ trình duyệt | ✅ Tất cả | ✅ Hiện đại | ✅ Hiện đại |
| Tốt nhất cho | Cập nhật thỉnh thoảng | Luồng từ máy chủ → khách hàng | Trò chuyện/h trò chơi hai chiều |
🔹 Hạn chế của SSE
- Chỉ hỗ trợ máy chủ → khách hàng (không phải hai chiều).
- Chỉ văn bản (không hỗ trợ nhị phân).
- Giới hạn kết nối của trình duyệt (~6 mỗi miền).
- Không hỗ trợ trên IE (nhưng hoạt động trên tất cả các trình duyệt hiện đại).
🔹 Kết luận
Nếu bạn cần cập nhật thời gian thực từ máy chủ → khách hàng mà không muốn độ phức tạp của WebSockets, SSE là lựa chọn hoàn hảo. Nó nhẹ, tích hợp sẵn trong trình duyệt và tuyệt vời cho các ứng dụng như thông báo, bảng điều khiển hoặc ghi lại nhật ký.
🔹 Các thực tiễn tốt nhất
- Sử dụng kết nối an toàn: Hãy luôn sử dụng HTTPS để bảo vệ dữ liệu của bạn.
- Kiểm tra kết nối: Theo dõi trạng thái kết nối để có thể xử lý các lỗi kịp thời.
- Giới hạn dữ liệu gửi: Đảm bảo rằng bạn không gửi quá nhiều dữ liệu trong mỗi thông điệp để tránh tắc nghẽn.
🔹 Những cạm bẫy thường gặp
- Quên dọn dẹp: Hãy luôn đóng kết nối khi không còn sử dụng để giải phóng tài nguyên.
- Bỏ qua lỗi: Đừng quên xử lý các lỗi để cải thiện trải nghiệm người dùng.
🔹 Mẹo hiệu suất
- Giảm tần suất gửi: Chỉ gửi dữ liệu khi thực sự cần thiết, ví dụ như khi có thay đổi giá trị.
- Sử dụng bộ nhớ cache: Tránh gửi dữ liệu trùng lặp bằng cách sử dụng bộ nhớ cache.
🔹 Câu hỏi thường gặp
1. SSE có an toàn không?
Có, nếu bạn sử dụng HTTPS, dữ liệu sẽ được mã hóa khi truyền tải.
2. SSE có được hỗ trợ trên tất cả các trình duyệt không?
SSE được hỗ trợ trên hầu hết các trình duyệt hiện đại nhưng không hỗ trợ trên Internet Explorer.
3. Tôi có thể gửi dữ liệu nhị phân qua SSE không?
Không, SSE chỉ hỗ trợ dữ liệu dạng văn bản.
✍️ Viết bởi [Srinivasa Reddy Thumu]
🔗 Hãy kết nối với tôi trên LinkedIn