0
0
Lập trình
Sơn Tùng Lê
Sơn Tùng Lê103931498422911686980

Sự kiện máy chủ gửi (SSE) - Cập nhật thời gian thực dễ dàng

Đăng vào 8 tháng trước

• 5 phút đọc

Chủ đề:

#react

🔹 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:

  1. Khách hàng mở một kết nối sử dụng EventSource.
  2. Máy chủ phản hồi với Content-Type: text/event-stream.
  3. Máy chủ gửi các thông điệp theo định dạng đặc biệt.
  4. Trình duyệt chuyển tiếp các sự kiện đến ứng dụng JavaScript của bạn.
Copy
Khách hàng (EventSource)  <--- Luồng HTTP --->  Máy chủ

🔹 Ví dụ cơ bản

🖥️ Máy chủ (Node.js + Express)

Copy
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)

Copy
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ủ:

Copy
event: priceUpdate
data: 123.45

Khách hàng:

Copy
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, EventSource tự độ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:
Copy
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

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào