Trong các website hiện đại, người dùng ngày càng mong muốn dữ liệu được cập nhật nhanh chóng mà không cần liên tục tải lại trang. Server-Sent Events là công nghệ cho phép server chủ động gửi dữ liệu đến client theo thời gian thực thông qua một kết nối HTTP liên tục. Hiểu đơn giản, thay vì client phải liên tục hỏi server xem có dữ liệu mới hay chưa, server có thể chủ động gửi dữ liệu ngay khi có thay đổi. Đây là cách tiếp cận thường được sử dụng cho thông báo realtime, dashboard, tiến trình xử lý hoặc nội dung AI được trả về từng phần. Để hiểu rõ hơn SSE là gì, cách hoạt động, cách triển khai và khi nào nên sử dụng công nghệ này, cùng tìm hiểu chi tiết trong bài viết này!

- SSE là gì?
- Tại sao công nghệ SSE lại bùng nổ trong kỷ nguyên AI và web hiện đại?
- Cơ chế hoạt động của Server-Sent Events
- Ứng dụng của Server-Sent Events trong phát triển web
- Hướng dẫn triển khai SSE trong website thực tế
- Những lưu ý quan trọng khi triển khai Server-Sent Events
- Ưu điểm và hạn chế của công nghệ Server-Sent Events
- Trường hợp nên và không nên sử dụng công nghệ SSE
- So sánh sự khác biệt giữa SSE và WebSocket, Polling
- Sự kết hợp giữa SSE với các công nghệ khác
- Những câu hỏi thường gặp về công nghệ Server-Sent Events
- 1. SSE có phải là công nghệ giao tiếp hai chiều giữa client và server không?
- 2. Công nghệ SSE có hỗ trợ tất cả các trình duyệt hiện đại không?
- 3. Có thể gửi dữ liệu dạng nhị phân (Binary/File) qua SSE được không?
- 4. SSE có thể kết hợp với REST API trong cùng một website không?
- 5. Xử lý như thế nào khi kết nối SSE bị ngắt giữa chừng? Có bị mất dữ liệu không?
- 6. Làm thế nào để mở rộng hệ thống SSE cho hàng nghìn kết nối đồng thời trên website?
SSE là gì?
Server-Sent Events (SSE) là một công nghệ web cho phép server chủ động gửi dữ liệu liên tục đến client thông qua một kết nối HTTP duy trì mở. Thay vì client phải gửi request mới mỗi khi muốn kiểm tra dữ liệu, server có thể gửi thông tin xuống ngay khi có nội dung mới. SSE sử dụng chuẩn text/event-stream và hỗ trợ truyền dữ liệu theo thời gian thực theo một chiều từ server đến client.
Về cơ chế hoạt động, client trước tiên gửi request HTTP đến một endpoint SSE trên server. Sau khi nhận request, server không đóng kết nối ngay mà giữ connection ở trạng thái mở để có thể tiếp tục gửi dữ liệu. Mỗi khi phát sinh thông tin mới, server gửi một event qua kết nối này; client nhận và xử lý event ngay khi dữ liệu được truyền đến.
Công nghệ Server-Sent Events đặc biệt phù hợp với những trường hợp server cần liên tục cập nhật dữ liệu cho client nhưng không yêu cầu truyền dữ liệu hai chiều. Một số ví dụ phổ biến gồm streaming câu trả lời từ LLM, thông báo thời gian thực, trạng thái xử lý tác vụ, cập nhật bảng điều khiển hoặc dữ liệu thay đổi liên tục. Khi kết nối bị gián đoạn, trình duyệt còn có thể tự động thực hiện kết nối lại, giúp duy trì quá trình nhận dữ liệu ổn định hơn.

Tại sao công nghệ SSE lại bùng nổ trong kỷ nguyên AI và web hiện đại?
Trong vài năm gần đây, Server-Sent Events ngày càng được sử dụng rộng rãi trong các hệ thống AI và nền tảng web hiện đại, đặc biệt với những hệ thống cần truyền dữ liệu theo thời gian thực. Sự phát triển này đến từ nhu cầu streaming phản hồi AI, yêu cầu tương tác nhanh và khả năng tích hợp đơn giản với hạ tầng web hiện có.
- Phù hợp với cơ chế AI streaming: Các mô hình AI thường không cần chờ tạo xong toàn bộ câu trả lời mới trả kết quả. Backend có thể nhận từng phần nội dung từ AI API và chuyển ngay xuống trình duyệt thông qua SSE. Nhờ đó, người dùng nhìn thấy câu trả lời xuất hiện liên tục thay vì phải chờ toàn bộ quá trình xử lý hoàn tất.
- Tạo trải nghiệm realtime tự nhiên hơn: Web hiện đại ngày càng cần cập nhật dữ liệu mà không yêu cầu người dùng tải lại trang. SSE cho phép server chủ động gửi thông báo, trạng thái xử lý, dữ liệu dashboard hoặc các thay đổi mới ngay khi chúng phát sinh. Điều này đặc biệt phù hợp với những giao diện có dữ liệu thay đổi liên tục nhưng phần lớn thông tin vẫn đi theo một chiều từ server đến client.
- Tận dụng nền tảng HTTP quen thuộc: Server-Sent Events hoạt động trên HTTP nên có thể tận dụng nhiều thành phần quen thuộc trong kiến trúc web như reverse proxy, load balancer, authentication và hệ thống server hiện có. So với việc xây dựng một cơ chế realtime hoàn toàn riêng biệt, SSE thường dễ tích hợp vào các ứng dụng web vốn đã sử dụng HTTP và REST API.
- Đơn giản hóa việc triển khai phía frontend: Trình duyệt có sẵn EventSource API, giúp frontend dễ dàng tạo và duy trì kết nối SSE để nhận dữ liệu từ server. SSE cũng hỗ trợ tự động kết nối lại khi bị gián đoạn, phù hợp với các tính năng cần cập nhật dữ liệu liên tục từ server.
- Đáp ứng xu hướng ứng dụng AI và dữ liệu realtime: AI chatbot, trợ lý AI, dashboard realtime và các tác vụ xử lý nền đều có điểm chung là cần đưa dữ liệu đến giao diện ngay khi dữ liệu sẵn sàng. SSE đáp ứng tốt mô hình này vì server có thể duy trì kết nối và gửi từng event theo thời gian thực. Vì vậy, sự phát triển của AI streaming và các trải nghiệm web realtime đang làm Server-Sent Events trở thành một lựa chọn đáng chú ý trong kiến trúc web hiện đại.

Cơ chế hoạt động của Server-Sent Events
Công nghệ Server-Sent Events hoạt động dựa trên một kết nối HTTP được duy trì liên tục giữa client và server. Sau khi kết nối được thiết lập, server có thể chủ động gửi dữ liệu mới đến client theo thời gian thực mà không cần client liên tục gửi request để kiểm tra. Dưới đây là chi tiết cách hoạt động của công nghệ Server-Sent Events:
1. Quá trình bắt tay (handshake)
Quá trình bắt tay của SSE bắt đầu khi client gửi một HTTP request đến endpoint hỗ trợ SSE. Request này thường chứa header Accept: text/event-stream để thông báo cho server rằng client muốn nhận dữ liệu theo dạng luồng sự kiện.
- Client khởi tạo kết nối: Trình duyệt sử dụng API EventSource để kết nối đến một endpoint SSE trên server, chẳng hạn new EventSource('/api/stream'). Khi đó, trình duyệt tự động gửi một request GET đến endpoint được chỉ định.
- Client gửi header yêu cầu stream: Request thường đi kèm header Accept: text/event-stream, cho biết client mong muốn nhận dữ liệu dưới dạng một luồng sự kiện SSE thay vì một response HTTP thông thường.
- Server phản hồi với Content-Type phù hợp: Nếu endpoint hỗ trợ SSE, server trả về response với header Content-Type: text/event-stream. Header này cho biết nội dung phản hồi được truyền theo định dạng event stream và cần được xử lý theo cơ chế streaming.
- Server duy trì kết nối mở: Sau khi gửi response header, server không kết thúc connection ngay. Thay vào đó, kết nối HTTP được duy trì để server có thể tiếp tục gửi các event mới khi dữ liệu phát sinh. Client sẽ nhận và xử lý từng event ngay khi dữ liệu được truyền đến.
- Không cần nâng cấp giao thức: SSE không yêu cầu cơ chế HTTP Upgrade hay một quy trình handshake riêng như WebSocket. Toàn bộ quá trình thiết lập dựa trên request và response HTTP tiêu chuẩn, kết hợp với các header và kiểu nội dung dành cho event stream.

2. Định dạng dữ liệu server gửi đi
Sau khi kết nối Server-Sent Events được thiết lập, server không trả về dữ liệu theo dạng JSON hoặc HTML thông thường mà gửi một luồng sự kiện (event stream) với định dạng văn bản text/event-stream. Mỗi sự kiện gồm một hoặc nhiều dòng theo cấu trúc field: value, kết thúc bằng một dòng trống để báo cho client biết sự kiện đã hoàn chỉnh. Trong đó, data, event, id và retry là bốn trường quan trọng thường được sử dụng.
Trường data
Trường data là trường quan trọng nhất trong SSE, dùng để chứa nội dung dữ liệu mà server muốn gửi đến client. Giá trị của trường có thể là một chuỗi văn bản, thông báo, dữ liệu JSON hoặc bất kỳ nội dung nào mà ứng dụng cần truyền. Ví dụ, server có thể gửi data: {"message":"Có đơn hàng mới"} để thông báo cho giao diện khi phát sinh đơn hàng.
Một sự kiện có thể chứa nhiều dòng data liên tiếp. Khi đó, client sẽ ghép nội dung của các dòng này lại với nhau, ngăn cách bằng ký tự xuống dòng. Sau khi server gửi một dòng trống, trình duyệt hiểu rằng sự kiện đã kết thúc và chuyển dữ liệu cho mã JavaScript xử lý.
Trường event
Trường event dùng để đặt tên cho loại sự kiện mà server gửi đến client. Nếu server không khai báo trường này, sự kiện sẽ được xử lý dưới tên mặc định là message. Khi sử dụng event, một kết nối SSE có thể truyền nhiều loại thông báo khác nhau mà client vẫn phân biệt được từng loại.
Chẳng hạn, server có thể gửi event: notification cho thông báo mới và event: order-update khi trạng thái đơn hàng thay đổi. Phía client có thể đăng ký từng loại sự kiện bằng addEventListener() và thực hiện logic xử lý tương ứng.
Trường id
Trường id dùng để gán mã định danh cho từng sự kiện SSE. Sau khi nhận được giá trị này, trình duyệt sẽ ghi nhớ ID của sự kiện cuối cùng đã nhận. Nếu kết nối bị ngắt và trình duyệt tự động kết nối lại, nó có thể gửi ID này trong header Last-Event-ID của request mới.
Cơ chế này giúp server biết client đã nhận đến sự kiện nào và có thể tiếp tục gửi các sự kiện phù hợp thay vì bắt đầu lại từ đầu. Vì vậy, id đặc biệt hữu ích với các ứng dụng yêu cầu duy trì tính liên tục của dữ liệu, chẳng hạn bảng giá trực tuyến, thông báo hoặc trạng thái xử lý đơn hàng.
Trường retry
Trường retry cho phép server thiết lập khoảng thời gian chờ trước khi client thử kết nối lại nếu kết nối SSE bị gián đoạn. Giá trị của trường được tính bằng mili giây, chẳng hạn retry: 5000 yêu cầu client chờ khoảng 5 giây trước khi thực hiện lần kết nối lại tiếp theo.
Trường này giúp server kiểm soát phần nào tần suất reconnect của client, tránh việc client liên tục gửi request trong thời gian server gặp sự cố hoặc mạng không ổn định. Nếu server không gửi retry, trình duyệt sẽ sử dụng khoảng thời gian reconnect mặc định của mình.
3. Cơ chế tự động kết nối lại (Auto-reconnection & Resilience)
Một trong những đặc điểm quan trọng của Server-Sent Events là khả năng tự động phục hồi kết nối khi xảy ra gián đoạn. Cơ chế này được tích hợp sẵn trong chuẩn SSE, giúp giảm lượng logic mà lập trình viên phải tự xây dựng để duy trì kết nối trong môi trường mạng không ổn định.
- Trình duyệt tự phát hiện mất kết nối: Khi kết nối SSE bị gián đoạn do mất mạng, server khởi động lại, proxy timeout hoặc các lỗi network khác, trình duyệt có thể phát hiện trạng thái này thông qua đối tượng EventSource. Lập trình viên không cần tự viết cơ chế kiểm tra kết nối liên tục.
- Tự động gửi lại request kết nối: Sau khi phát hiện kết nối bị đóng, trình duyệt sẽ tự động gửi một HTTP GET request mới đến endpoint SSE ban đầu để thiết lập lại kết nối. Quá trình này diễn ra ở phía trình duyệt mà không yêu cầu người dùng tải lại trang.
- Điều chỉnh thời gian reconnect bằng retry: Server có thể sử dụng trường retry để chỉ định khoảng thời gian trình duyệt cần chờ trước khi thử kết nối lại. Giá trị được tính bằng mili giây, chẳng hạn retry: 5000 có nghĩa là trình duyệt chờ khoảng 5 giây trước khi thực hiện lần reconnect tiếp theo.
- Xác định sự kiện cuối cùng bằng Last-Event-ID: Mỗi sự kiện SSE có thể được gắn một giá trị id. Trình duyệt sẽ ghi nhớ ID của sự kiện gần nhất đã nhận và gửi lại giá trị này thông qua header Last-Event-ID khi thiết lập kết nối mới. Nhờ đó, server có thể biết client đã nhận dữ liệu đến đâu.
- Khôi phục dữ liệu bị gián đoạn: Dựa vào Last-Event-ID, server có thể xác định những sự kiện mà client chưa nhận được và gửi lại các dữ liệu bị bỏ lỡ. Để thực hiện điều này, server cần lưu trữ lịch sử sự kiện trong một khoảng thời gian nhất định, chẳng hạn trong bộ nhớ đệm hoặc cơ sở dữ liệu.
- Không cần thư viện reconnect riêng: Khả năng tự động kết nối lại được hỗ trợ trực tiếp bởi API EventSource trên trình duyệt. Vì vậy, phía client chỉ cần khởi tạo kết nối bằng new EventSource(url) mà không phải tự xây dựng toàn bộ logic phát hiện lỗi và reconnect.

Ứng dụng của Server-Sent Events trong phát triển web
Nhờ khả năng duy trì kết nối HTTP và truyền dữ liệu một chiều từ server đến client theo thời gian thực, Server-Sent Events phù hợp với nhiều hệ thống web cần cập nhật thông tin liên tục. Công nghệ này đặc biệt hiệu quả khi phần lớn dữ liệu được tạo ra ở phía server và người dùng chủ yếu cần nhận thông tin mới mà không phải gửi request liên tục.
1. Bảng điều khiển & thống kê thời gian thực (Live dashboards)
SSE phù hợp với các dashboard cần hiển thị số liệu thay đổi liên tục như doanh thu, số lượng đơn hàng, lượt truy cập, số người đang online hoặc trạng thái hoạt động của hệ thống. Sau khi client thiết lập kết nối công nghệ SSE, server có thể chủ động gửi dữ liệu mới ngay khi các chỉ số thay đổi mà không cần người dùng tải lại trang.
Ví dụ, trong một hệ thống quản lý bán hàng, khi có đơn hàng mới được tạo, server có thể gửi sự kiện chứa thông tin về đơn hàng và doanh thu mới đến dashboard. Phía client tiếp nhận dữ liệu rồi cập nhật các con số, biểu đồ hoặc trạng thái trên giao diện. Cách này giúp dashboard phản ánh dữ liệu gần với thời gian thực và hạn chế việc client phải liên tục gửi request để kiểm tra thay đổi.
2. Hệ thống thông báo đẩy (Real-time push notifications)
Công nghệ SSE phù hợp với hệ thống thông báo đẩy vì cho phép server chủ động gửi thông tin đến trình duyệt ngay khi có sự kiện mới mà không cần client liên tục gửi request để kiểm tra. Khi kết nối SSE được duy trì, các thông báo như đơn hàng thay đổi trạng thái, tin nhắn mới, cảnh báo hệ thống hoặc cập nhật tài khoản có thể được gửi đến giao diện gần như ngay lập tức.
Chẳng hạn, khi một đơn hàng chuyển từ trạng thái “Đang xử lý” sang “Đang giao”, backend có thể phát sinh một event và gửi qua SSE đến đúng người dùng. Frontend nhận event, đọc dữ liệu và cập nhật khu vực thông báo mà không cần tải lại trang hoặc thực hiện polling liên tục.
SSE cũng hỗ trợ đặt tên cho từng loại event như notification, order-update hoặc system-alert. Nhờ đó, frontend có thể xử lý từng nhóm thông báo theo logic riêng, chẳng hạn cập nhật biểu tượng chuông, hiển thị toast hoặc thay đổi trạng thái trên dashboard.
3. Streaming kết quả từ mô hình AI (LLMs streaming)
SSE ngày càng được sử dụng để truyền kết quả từ các mô hình ngôn ngữ lớn (LLMs) theo từng phần. Thay vì chờ mô hình hoàn thành toàn bộ câu trả lời rồi mới gửi về client, server có thể chuyển từng đoạn nội dung ngay khi chúng được tạo ra. Giao diện vì thế có thể hiển thị câu trả lời dần dần, tương tự cách người dùng nhìn thấy nội dung được "gõ" trực tiếp trên màn hình.
Ví dụ, khi người dùng gửi câu hỏi cho chatbot AI, server nhận yêu cầu và chuyển tiếp đến mô hình ngôn ngữ. Khi mô hình tạo ra từng phần kết quả, server gửi chúng qua kết nối SSE đến trình duyệt. Client tiếp nhận các phần dữ liệu này và nối chúng lại thành câu trả lời hoàn chỉnh. Cách truyền này đặc biệt hữu ích với những yêu cầu AI có thời gian xử lý dài. Người dùng có thể bắt đầu đọc phần đầu của câu trả lời trong khi mô hình vẫn đang tiếp tục tạo nội dung.

4. Cập nhật nội dung trực tiếp (Live feeds & scores)
SSE phù hợp với các trang có nội dung thay đổi thường xuyên và cần hiển thị dữ liệu mới ngay khi server nhận được thông tin. Một số trường hợp phổ biến gồm bảng tỷ số thể thao, tin tức trực tiếp, bảng giá, trạng thái giao dịch hoặc các luồng hoạt động trên nền tảng trực tuyến.
Ví dụ, với một trang theo dõi trận đấu, server có thể gửi sự kiện khi tỷ số thay đổi, có bàn thắng, thẻ phạt hoặc một sự kiện quan trọng xảy ra. Trình duyệt nhận dữ liệu và cập nhật khu vực tương ứng trên trang mà không cần tải lại toàn bộ nội dung. Tương tự, một trang hiển thị giá có thể nhận giá trị mới từ server và cập nhật ngay trên giao diện khi dữ liệu thay đổi. SSE giúp giảm nhu cầu polling liên tục, bởi client không cần gửi request theo chu kỳ để hỏi "dữ liệu đã thay đổi chưa?" mà chỉ chờ server gửi thông tin mới khi có sự kiện.
5. Theo dõi tiến độ tác vụ chạy ngầm (Background job tracking)
Công nghệ SSE cũng phù hợp với các tác vụ cần nhiều thời gian xử lý ở phía server như xuất báo cáo, xử lý dữ liệu lớn, chuyển đổi tệp, nhập dữ liệu hàng loạt hoặc tạo nội dung. Trong quá trình xử lý, server có thể gửi trạng thái mới đến client để giao diện phản ánh tiến độ theo thời gian thực.
Cách này giúp người dùng biết chính xác tác vụ đang ở trạng thái nào thay vì phải chờ một request duy nhất trả về kết quả cuối cùng. Đồng thời, server không cần nhận liên tục các request kiểm tra tiến độ từ client. Với những tác vụ kéo dài, SSE còn có thể kết hợp trường id và Last-Event-ID để hỗ trợ duy trì luồng thông tin nếu kết nối bị gián đoạn trong quá trình xử lý.

Hướng dẫn triển khai SSE trong website thực tế
Để triển khai Server-Sent Events, frontend và backend cần phối hợp để thiết lập một kết nối HTTP liên tục. Phía frontend sử dụng API EventSource có sẵn trên trình duyệt để mở kết nối, lắng nghe dữ liệu và xử lý các sự kiện từ server. Trong khi đó, server chịu trách nhiệm duy trì luồng dữ liệu và gửi các event theo đúng định dạng SSE. Dưới đây là các bước triển khai SSE ở frontend và backend, từ thiết lập kết nối đến xử lý dữ liệu và quản lý vòng đời kết nối.
1. Triển khai SSE ở phía frontend
Ở phía frontend, quá trình làm việc với SSE tương đối đơn giản vì trình duyệt đã cung cấp sẵn EventSource API. Lập trình viên chủ yếu cần xác định endpoint SSE, đăng ký các trình xử lý sự kiện và quản lý vòng đời của kết nối. Cách triển khai này không yêu cầu cài thêm thư viện bên ngoài cho các chức năng SSE cơ bản.
Khởi tạo kết nối với EventSource API
EventSource là API JavaScript được sử dụng để thiết lập kết nối SSE từ trình duyệt đến server. Lập trình viên chỉ cần truyền URL của endpoint SSE vào hàm khởi tạo:
const event Source = new Event Source('/api/events');
Sau khi đoạn mã trên được thực thi, trình duyệt sẽ gửi HTTP request đến /api/events và chờ server trả về luồng dữ liệu với Content-Type: text/event-stream. Khi kết nối được thiết lập thành công, server có thể gửi các sự kiện mới đến client bất cứ khi nào có dữ liệu.
Có thể kiểm tra trạng thái kết nối thông qua thuộc tính readyState của đối tượng EventSource. Giá trị EventSource.OPEN cho biết kết nối đang hoạt động, trong khi EventSource.CONNECTING cho biết trình duyệt đang thiết lập hoặc thiết lập lại kết nối.
Lắng nghe các sự kiện mặc định
Nếu server gửi dữ liệu SSE mà không khai báo trường event, trình duyệt sẽ xử lý đó là sự kiện mặc định có tên message. Frontend có thể lắng nghe loại sự kiện này thông qua onmessage hoặc addEventListener():
event Source.onmessage = (event) => {
console.log('Dữ liệu nhận được:', event.data);
};
Nội dung server gửi trong trường data sẽ được cung cấp thông qua thuộc tính event.data. Nếu server gửi dữ liệu JSON, frontend có thể chuyển chuỗi nhận được thành object JavaScript bằng JSON.parse() để tiếp tục xử lý:
eventSource. onmessage = (event) => {
const data = JSON. parse(event.data);
console.log(data);
};
Cách này phù hợp với những trường hợp website chỉ cần một loại event chính, chẳng hạn nhận thông báo mới, cập nhật số liệu hoặc trạng thái của một tác vụ.
Bắt các custom events tự định nghĩa
SSE cho phép server tự định nghĩa tên sự kiện thông qua trường event. Frontend có thể lắng nghe từng custom event bằng addEventListener() để thực hiện các logic khác nhau.
Ví dụ, server gửi:
event : order-update
data: {" status":"shipping"}
Frontend có thể bắt sự kiện bằng:
eventSource.addEventListener(' order-update', (event) => {
const data = JSON. parse(event.data);
console.log(' Trạng thái đơn hàng:', data.status);
});
Cách tổ chức này đặc biệt hữu ích khi một kết nối SSE phải truyền nhiều loại dữ liệu. Chẳng hạn, cùng một kết nối có thể nhận notification, order-update và system-alert. Mỗi loại event được xử lý bởi một listener riêng, giúp mã frontend rõ ràng và dễ mở rộng hơn.
Quản lý kết nối & đóng luồng
Mặc dù EventSource có khả năng tự động kết nối lại khi luồng bị gián đoạn, frontend vẫn cần quản lý vòng đời của kết nối. Khi không còn nhu cầu nhận dữ liệu, có thể đóng kết nối bằng phương thức close(): eventSource.close();
Sau khi close() được gọi, trình duyệt sẽ dừng kết nối SSE và không tiếp tục tự động reconnect. Điều này cần thiết khi người dùng rời khỏi một trang, đăng xuất hoặc không còn theo dõi dữ liệu để tránh duy trì các kết nối không cần thiết.
Frontend cũng nên xử lý sự kiện error để biết khi kết nối gặp vấn đề:
eventSource. onerror = (error) => {
console.error ('SSE connection error:', error);
};
Không nên mặc định rằng mọi error đều có nghĩa kết nối đã mất hoàn toàn, bởi EventSource có thể tự động thử kết nối lại. Đóng kết nối chỉ nên thực hiện khi ứng dụng thực sự không còn cần luồng dữ liệu.
2. Triển khai SSE ở phía backend
Phía backend giữ vai trò tạo và duy trì HTTP connection để liên tục gửi các sự kiện đến client. Khác với frontend chỉ cần sử dụng EventSource, backend phải thiết lập đúng response header, định dạng dữ liệu theo chuẩn SSE và kiểm soát vòng đời của từng kết nối. Khi các thành phần này được cấu hình chính xác, trình duyệt có thể nhận và xử lý dữ liệu ngay khi server phát sinh sự kiện mới.
Thiết lập Response Header đặt chuẩn SSE
Backend cần trả về các HTTP response header phù hợp để trình duyệt nhận biết đây là một luồng SSE thay vì một response HTTP thông thường. Header quan trọng nhất là Content-Type: text/event-stream, cho biết nội dung response được truyền dưới dạng event stream.
Thông thường, server cũng nên sử dụng Cache-Control: no-cache để hạn chế việc cache dữ liệu SSE. Trong một số môi trường, có thể cần thêm các cấu hình liên quan đến proxy hoặc buffering để dữ liệu được chuyển đến client ngay khi server gửi thay vì bị giữ lại và gửi theo từng nhóm.
Ví dụ response header cơ bản có thể có dạng:
Content-Type : text/event-stream
Cache-Control : no-cache
Connection : keep-alive
Trong đó, Connection: keep-alive thể hiện mục đích duy trì kết nối để server có thể tiếp tục gửi nhiều sự kiện trên cùng một HTTP connection.
Quy định định dạng dữ liệu gửi đi
Sau khi thiết lập response, backend phải gửi dữ liệu theo đúng định dạng của SSE. Mỗi trường được viết trên một dòng theo cấu trúc field: value, trong đó data là trường chứa nội dung chính. Một sự kiện hoàn chỉnh được kết thúc bằng một dòng trống để client biết rằng dữ liệu của event đã được gửi xong.
Ví dụ, server có thể gửi:
event : notification
id : 123
data : {"message":"Bạn có đơn hàng mới"}
Trong trường hợp chỉ cần gửi dữ liệu thông thường, có thể sử dụng:
data : {"message":"Hello from server"}
Backend cũng có thể sử dụng các trường event, id và retry khi cần. event giúp phân loại sự kiện, id hỗ trợ xác định vị trí của event khi kết nối lại, còn retry cho phép server chỉ định khoảng thời gian client nên chờ trước khi reconnect.
Quản lý vòng đời kết nối
Một kết nối SSE có thể được duy trì trong thời gian dài nên backend cần chủ động quản lý vòng đời của từng connection. Khi client kết nối, server có thể đăng ký client vào một danh sách hoặc cơ chế quản lý kết nối để biết những client nào đang chờ nhận dữ liệu. Khi có sự kiện mới, server gửi dữ liệu đến các connection phù hợp.
Server cũng cần phát hiện và xử lý những connection đã bị đóng. Điều này có thể xảy ra khi người dùng đóng trang, chuyển sang một trang khác, gọi eventSource.close() hoặc mất kết nối mạng. Nếu backend tiếp tục giữ các connection này trong bộ nhớ, hệ thống có thể phát sinh connection tồn đọng và tiêu tốn tài nguyên.
Với các hệ thống có nhiều client, quản lý connection càng quan trọng. Backend có thể cần giới hạn số lượng kết nối, giải phóng tài nguyên khi client disconnect và sử dụng cơ chế heartbeat để kiểm tra trạng thái kết nối trong những môi trường có proxy hoặc load balancer. Đồng thời, nếu hệ thống cần đảm bảo client không bỏ lỡ event khi reconnect, backend nên lưu lại một lượng lịch sử sự kiện cần thiết và xử lý giá trị Last-Event-ID do client gửi lên.

Những lưu ý quan trọng khi triển khai Server-Sent Events
SSE khá đơn giản ở phía client nhưng khi triển khai thực tế, hệ thống cần xử lý thêm nhiều vấn đề liên quan đến kết nối dài hạn, hạ tầng máy chủ và bảo mật. Đặc biệt, một kết nối SSE có thể tồn tại trong thời gian dài nên cách cấu hình HTTP server, reverse proxy và cơ chế xác thực cần được tính toán phù hợp để tránh gián đoạn hoặc tiêu tốn tài nguyên không cần thiết. Dưới đây là một số lưu ý quan trọng khi triển khai công nghệ Server-Sent Events:
1. Quản lý kết nối & giới hạn HTTP
SSE duy trì một HTTP connection trong thời gian dài, vì vậy số lượng client kết nối đồng thời có thể ảnh hưởng đáng kể đến tài nguyên của server. Khi có hàng nghìn hoặc hàng chục nghìn người dùng cùng mở kết nối, hệ thống cần tính toán giới hạn connection, số lượng file descriptor, memory và khả năng xử lý của web server. Backend cũng cần chủ động giải phóng connection khi client đóng trang hoặc không còn nhu cầu nhận dữ liệu.
Ngoài ra, cần phân biệt SSE với các HTTP request thông thường có thời gian phản hồi ngắn. Áp dụng timeout quá thấp có thể khiến server hoặc hệ thống trung gian tự động đóng kết nối trước khi client nhận được dữ liệu mới. Với những hệ thống có lượng truy cập lớn, có thể cân nhắc phân phối kết nối qua nhiều server và sử dụng cơ chế quản lý trạng thái phù hợp để tránh một máy chủ phải duy trì quá nhiều connection cùng lúc.
2. Cấu hình reverse proxy & web server
Reverse proxy và web server có thể ảnh hưởng trực tiếp đến khả năng truyền dữ liệu theo thời gian thực của SSE. Một số hệ thống mặc định bật response buffering, khiến dữ liệu server đã gửi bị giữ lại ở proxy thay vì chuyển ngay đến trình duyệt. Kết quả là client có thể nhận nhiều event cùng lúc sau một khoảng thời gian, làm mất đặc tính cập nhật gần thời gian thực của SSE.
Do đó, khi triển khai SSE qua Nginx, Apache hoặc các reverse proxy khác, cần kiểm tra và điều chỉnh các thiết lập liên quan đến buffering, timeout và connection. Server cũng nên gửi đúng Content-Type: text/event-stream và hạn chế cơ chế cache đối với event stream. Nếu hệ thống sử dụng load balancer, cần kiểm tra thêm cách load balancer duy trì các kết nối dài hạn và thời gian timeout của từng lớp trong kiến trúc.
SSE vẫn cần được bảo vệ giống các API hoặc endpoint khác, đặc biệt khi luồng dữ liệu chứa thông tin riêng tư hoặc dữ liệu của người dùng. Server cần xác định người đang mở kết nối là ai và họ có quyền nhận những event nào trước khi bắt đầu truyền dữ liệu. Không nên chỉ dựa vào việc client biết URL của endpoint SSE để quyết định quyền truy cập.
Với các website sử dụng cookie-based authentication, trình duyệt có thể gửi cookie phiên cùng request SSE trong những điều kiện phù hợp. Nếu sử dụng cơ chế xác thực khác, cần cân nhắc cách truyền credential vì API EventSource tiêu chuẩn không cung cấp tùy chọn tùy ý thêm HTTP header Authorization. Trong trường hợp cần cơ chế xác thực phức tạp hơn, kiến trúc có thể phải sử dụng cookie, token trong URL với những cân nhắc bảo mật phù hợp hoặc giải pháp client khác.
4. Quản lý bộ nhớ & gói tin heartbeat
SSE duy trì kết nối HTTP trong thời gian dài nên backend cần đặc biệt chú ý đến việc sử dụng bộ nhớ và tài nguyên cho từng connection. Nếu server lưu toàn bộ trạng thái, dữ liệu hoặc lịch sử sự kiện của từng client trong bộ nhớ mà không có giới hạn, lượng memory tiêu thụ có thể tăng nhanh khi số lượng kết nối đồng thời lớn. Vì vậy, chỉ nên lưu những thông tin thực sự cần thiết, đồng thời giải phóng tài nguyên ngay khi client ngắt kết nối.
Bên cạnh đó, server có thể gửi heartbeat định kỳ để duy trì kết nối và phát hiện những connection không còn hoạt động. Trong SSE, heartbeat thường được gửi dưới dạng comment bắt đầu bằng dấu : và không tạo ra một event mà client phải xử lý. Ví dụ: : heartbeat
Các gói heartbeat giúp tạo ra lưu lượng nhỏ trên kết nối, từ đó hạn chế việc một số proxy, load balancer hoặc firewall đóng connection do không có dữ liệu trong thời gian dài. Khoảng thời gian gửi heartbeat cần được lựa chọn phù hợp với timeout của hạ tầng mạng; không nên gửi quá thường xuyên vì sẽ tạo thêm lưu lượng và chi phí xử lý không cần thiết.
5. Cơ chế khôi phục dữ liệu bị gián đoạn
Server-Sent Events có cơ chế hỗ trợ client tiếp tục nhận dữ liệu sau khi kết nối bị gián đoạn thông qua hai thành phần id và Last-Event-ID. Mỗi event có thể được server gắn một mã định danh bằng trường id. Khi client nhận được event, trình duyệt sẽ ghi nhớ ID của event đó để sử dụng trong trường hợp phải thiết lập lại kết nối.
Khi kết nối bị mất và EventSource tự động reconnect, trình duyệt có thể gửi header Last-Event-ID trong request mới. Giá trị này cho server biết event cuối cùng mà client đã nhận được trước khi kết nối bị gián đoạn. Ví dụ, nếu client đã nhận event có id: 105 nhưng chưa nhận các event từ 106 trở đi, request reconnect có thể chứa Last-Event-ID: 105.
Phía server cần dựa vào giá trị này để xác định những event mà client có thể đã bỏ lỡ. Nếu hệ thống có lưu lịch sử event, server có thể tìm các event sau ID 105 và gửi lại cho client trước khi tiếp tục truyền những dữ liệu mới. Cách này giúp hạn chế tình trạng mất dữ liệu trong khoảng thời gian kết nối bị gián đoạn.
6. Xử lý reconnect và duplicate event
Khi kết nối SSE bị gián đoạn, EventSource có thể tự động reconnect đến endpoint ban đầu. Trong quá trình này, client có thể nhận lại một event đã từng nhận trước đó, đặc biệt khi server sử dụng Last-Event-ID để gửi lại các sự kiện gần nhất. Vì vậy, backend và frontend cần có cơ chế xử lý duplicate event để tránh việc một dữ liệu được áp dụng nhiều lần.
Một cách phổ biến là gắn ID duy nhất cho mỗi event thông qua trường id. Khi reconnect, server đọc giá trị Last-Event-ID và xác định các event cần gửi lại. Backend nên đảm bảo thứ tự ID rõ ràng và có khả năng xác định event nào đã được client nhận trước đó. Ví dụ, nếu client đã nhận đến id: 100, server có thể tiếp tục gửi từ event 101 thay vì gửi lại toàn bộ dữ liệu.

Ưu điểm và hạn chế của công nghệ Server-Sent Events
Server-Sent Events cung cấp cơ chế truyền dữ liệu một chiều theo thời gian thực từ server đến client thông qua kết nối HTTP được duy trì liên tục. Công nghệ này có cách triển khai tương đối đơn giản và phù hợp với nhiều hệ thống cần cập nhật dữ liệu thường xuyên, nhưng vẫn có những giới hạn nhất định khi yêu cầu giao tiếp hai chiều hoặc xử lý số lượng kết nối rất lớn.
1. Ưu điểm của công nghệ SSE
SSE tập trung vào bài toán server chủ động đẩy dữ liệu đến client, vì vậy kiến trúc và cách triển khai thường đơn giản hơn so với những giải pháp yêu cầu giao tiếp hai chiều liên tục. Một số ưu điểm đáng chú ý gồm:
- Triển khai đơn giản với HTTP: Server-Sent Events hoạt động trên HTTP/HTTPS thông thường và không yêu cầu một giao thức riêng. Phía frontend có thể sử dụng API EventSource có sẵn trên trình duyệt để mở kết nối, lắng nghe event và nhận dữ liệu từ server. Điều này giúp giảm lượng mã cần viết và không nhất thiết phải cài đặt thêm thư viện cho những nhu cầu SSE cơ bản.
- Hỗ trợ truyền dữ liệu theo thời gian thực: Sau khi kết nối được thiết lập, server có thể gửi dữ liệu ngay khi có sự kiện mới mà không cần client liên tục gửi request kiểm tra. Cách này phù hợp với dashboard, thông báo, trạng thái đơn hàng, tiến độ tác vụ, bảng tỷ số hoặc các nội dung cần cập nhật thường xuyên.
- Có cơ chế tự động reconnect: EventSource có khả năng tự động thử kết nối lại khi connection bị gián đoạn. Server có thể sử dụng trường retry để điều chỉnh khoảng thời gian chờ trước khi reconnect. Nhờ đó, lập trình viên không phải tự xây dựng toàn bộ cơ chế phát hiện mất kết nối và thiết lập lại connection ở phía client.
- Hỗ trợ khôi phục dữ liệu thông qua Last-Event-ID: Server có thể gắn id cho từng event để client xác định sự kiện cuối cùng đã nhận. Khi reconnect, trình duyệt có thể gửi Last-Event-ID để server biết client đã nhận dữ liệu đến đâu. Nếu backend lưu lịch sử event, hệ thống có thể gửi lại những dữ liệu bị bỏ lỡ trong thời gian kết nối gián đoạn.
- Có thể phân loại nhiều loại sự kiện: SSE hỗ trợ trường event, cho phép server đặt tên cho từng loại event. Client có thể đăng ký listener riêng cho từng loại như notification, order-update hoặc system-alert. Điều này giúp một connection có thể phục vụ nhiều luồng thông tin mà không cần tạo một connection riêng cho từng loại dữ liệu.
- Phù hợp với streaming dữ liệu: SSE có thể truyền dữ liệu từng phần thay vì chờ toàn bộ response hoàn thành. Đặc điểm này đặc biệt hữu ích khi hiển thị kết quả được tạo dần theo thời gian, chẳng hạn nội dung từ LLM, log xử lý hoặc tiến trình của một tác vụ dài.
2. Hạn chế của Server-Sent Events
Bên cạnh những ưu điểm trên, SSE không phải lựa chọn phù hợp cho mọi loại hệ thống realtime. Do được thiết kế chủ yếu cho giao tiếp một chiều từ server đến client, công nghệ này có một số giới hạn cần cân nhắc trước khi triển khai.
- Chỉ hỗ trợ giao tiếp một chiều: Công nghệ SSE cho phép server gửi dữ liệu đến client nhưng không cung cấp một kênh hai chiều tương đương trong cùng connection. Nếu client cần liên tục gửi dữ liệu realtime ngược lại server, chẳng hạn trong game online hoặc ứng dụng cộng tác trực tiếp, thường phải kết hợp thêm HTTP request hoặc lựa chọn công nghệ hỗ trợ hai chiều như WebSocket.
- Duy trì connection lâu dài tiêu tốn tài nguyên server: Mỗi client có thể duy trì một connection trong thời gian dài. Khi số lượng user tăng lên, server phải quản lý đồng thời nhiều connection, file descriptor, memory và các tài nguyên liên quan. Nếu không có chiến lược quản lý connection phù hợp, hệ thống có thể gặp vấn đề về khả năng mở rộng.
- Phụ thuộc vào cấu hình proxy và web server: Reverse proxy, load balancer hoặc web server có thể áp dụng buffering và timeout đối với HTTP response. Nếu không được cấu hình phù hợp, event có thể bị giữ lại thay vì chuyển ngay đến client hoặc connection có thể bị đóng sau một khoảng thời gian. Vì vậy, triển khai công nghệ SSE trong môi trường production cần kiểm tra toàn bộ chuỗi hạ tầng trung gian.
- Không phù hợp với dữ liệu nhị phân: SSE sử dụng event stream dạng văn bản với Content-Type: text/event-stream. Nếu hệ thống cần truyền lượng lớn dữ liệu nhị phân như hình ảnh, âm thanh hoặc dữ liệu game, SSE không phải lựa chọn tối ưu. Những trường hợp này có thể cần cơ chế truyền dữ liệu khác phù hợp hơn.
- Giới hạn khả năng mở rộng khi có nhiều connection: Khi số lượng người dùng đồng thời rất lớn, việc duy trì hàng nghìn hoặc hàng triệu connection SSE đặt ra yêu cầu cao đối với kiến trúc server. Hệ thống có thể cần load balancing, connection management, cơ chế phân phối event và các thành phần lưu trữ hoặc message broker để phân phối dữ liệu giữa nhiều server.

Trường hợp nên và không nên sử dụng công nghệ SSE
SSE phù hợp với những website cần server liên tục gửi dữ liệu mới đến người dùng mà không cần người dùng gửi request liên tục. Công nghệ này đặc biệt hữu ích cho thông báo realtime, dashboard, tiến trình xử lý hoặc nội dung được cập nhật thường xuyên. Ngược lại, nếu website cần giao tiếp hai chiều liên tục hoặc truyền dữ liệu nhị phân, SSE có thể không phải lựa chọn phù hợp. Dưới đây là những trường hợp nên sử dụng SSE và những tình huống cần cân nhắc lựa chọn công nghệ khác.
1. Những website nên sử dụng Server-Sent Events
SSE có thể phát huy hiệu quả khi website cần cập nhật thông tin liên tục nhưng không yêu cầu giao tiếp hai chiều phức tạp. Một số trường hợp phù hợp gồm:
- Website có dashboard và số liệu thời gian thực: Các hệ thống quản trị cần liên tục cập nhật doanh thu, đơn hàng, lượt truy cập, trạng thái server hoặc các chỉ số vận hành có thể sử dụng SSE. Server chỉ cần gửi phần dữ liệu thay đổi đến trình duyệt khi có số liệu mới, giúp dashboard cập nhật mà không cần người dùng refresh hoặc client liên tục polling.
- Website có hệ thống thông báo realtime: SSE phù hợp với các nền tảng cần gửi thông báo từ server đến người dùng như trạng thái đơn hàng, thông báo tài khoản, cảnh báo hệ thống hoặc thông tin mới. Khi phát sinh sự kiện, server có thể đẩy thông báo trực tiếp đến trình duyệt thông qua connection đang mở.
- Website hiển thị tiến độ xử lý tác vụ: Với các tác vụ chạy trong thời gian dài như xuất báo cáo, xử lý dữ liệu, upload và phân tích tệp, SSE có thể truyền trạng thái tiến độ đến giao diện. Server có thể gửi các mốc như 20%, 50%, 80% và 100%, giúp người dùng theo dõi quá trình mà không cần liên tục gửi request hỏi trạng thái.
- Website có nội dung cập nhật liên tục: Các trang hiển thị bảng tỷ số, tin tức trực tiếp, bảng giá hoặc live feed có thể sử dụng SSE để nhận dữ liệu mới ngay khi server có thay đổi. Đây là mô hình phù hợp vì phần lớn dữ liệu được truyền theo một hướng từ server đến nhiều client đang theo dõi.
- Website cần streaming nội dung từ AI: SSE phù hợp với chatbot và các tính năng sử dụng LLM khi kết quả được tạo từng phần. Server có thể gửi từng đoạn nội dung về trình duyệt ngay khi mô hình tạo ra, thay vì chờ toàn bộ câu trả lời hoàn tất. Điều này đặc biệt hữu ích với những phản hồi dài cần thời gian xử lý.
- Website chủ yếu cần server push: Nếu phần lớn hoạt động realtime của hệ thống là server gửi dữ liệu đến client và client chỉ thỉnh thoảng gửi request HTTP thông thường lên server, SSE là một lựa chọn đáng cân nhắc. Mô hình này giúp kiến trúc đơn giản hơn so với việc duy trì một kênh giao tiếp hai chiều khi hệ thống thực tế không cần đến nó.
2. Trường hợp nên cân nhắc sử dụng công nghệ khác
SSE có những giới hạn về hướng truyền dữ liệu và cách duy trì connection. Khi yêu cầu của hệ thống vượt quá mô hình server-to-client, nên cân nhắc các công nghệ khác phù hợp hơn:
- Website yêu cầu giao tiếp hai chiều theo thời gian thực: Các hệ thống như chat realtime, ứng dụng cộng tác trực tuyến hoặc game multiplayer thường cần client và server liên tục gửi dữ liệu cho nhau. Trong trường hợp này, WebSocket có thể phù hợp hơn vì cung cấp kênh giao tiếp hai chiều trên cùng một connection.
- Hệ thống có yêu cầu realtime hai chiều với độ trễ rất thấp: Những hệ thống cần client gửi dữ liệu liên tục và server phản hồi ngay lập tức có thể không phù hợp với mô hình SSE. Việc phải kết hợp SSE với các HTTP request riêng để truyền dữ liệu từ client lên server có thể khiến kiến trúc phức tạp hơn so với việc sử dụng một kênh hai chiều.
- Hệ thống có số lượng connection đồng thời cực lớn: SSE duy trì một HTTP connection cho mỗi client nên backend phải quản lý nhiều connection lâu dài. Với hệ thống có lượng người dùng đồng thời rất lớn, cần đánh giá kỹ giới hạn tài nguyên, load balancing, reverse proxy và cách phân phối event. Trong một số kiến trúc, các giải pháp realtime khác có thể phù hợp hơn về khả năng mở rộng.
- Hệ thống yêu cầu cơ chế truyền tin chính xác và phức tạp: SSE có hỗ trợ id và Last-Event-ID để phục hồi dữ liệu sau reconnect nhưng đảm bảo không mất hoặc xử lý trùng event vẫn cần backend tự thiết kế. Nếu hệ thống yêu cầu mô hình delivery phức tạp, hàng đợi tin nhắn, xác nhận message hoặc xử lý trạng thái phân tán, nên cân nhắc message broker hoặc kiến trúc chuyên biệt thay vì chỉ dựa vào SSE.
- Môi trường hạ tầng khó duy trì HTTP connection dài hạn: Nếu hệ thống nằm sau nhiều lớp proxy, firewall hoặc load balancer có timeout ngắn và khó kiểm soát, SSE có thể gặp tình trạng connection bị ngắt thường xuyên. Khi đó, cần đánh giá khả năng điều chỉnh hạ tầng hoặc lựa chọn phương thức giao tiếp phù hợp với môi trường triển khai.

So sánh sự khác biệt giữa SSE và WebSocket, Polling
SSE và WebSocket, Polling đều có thể được sử dụng để cập nhật dữ liệu trên website nhưng khác nhau về cách thiết lập kết nối, hướng truyền dữ liệu và mức độ phù hợp với từng loại hệ thống. SSE tập trung vào truyền dữ liệu một chiều từ server đến client, WebSocket hỗ trợ giao tiếp hai chiều liên tục, còn Polling dựa trên việc client gửi request định kỳ để kiểm tra dữ liệu mới. Bảng so sánh SSE và WebSocket, Polling dưới đây sẽ giúp bạn dễ dàng phân biệt cách hoạt động, ưu điểm và trường hợp phù hợp của từng công nghệ.
| Tiêu chí | SSE | WebSocket | Polling |
| Mô hình giao tiếp | Một chiều: server → client. | Hai chiều: client ↔ server. | Client → server theo từng request. |
| Giao thức | HTTP/HTTPS. | WebSocket (ws/wss). | HTTP/HTTPS. |
| Cách truyền dữ liệu | Server đẩy event khi có dữ liệu mới. | Hai bên có thể gửi dữ liệu bất kỳ lúc nào. | Client gửi request định kỳ để lấy dữ liệu. |
| Kết nối | HTTP connection được duy trì lâu dài. | WebSocket connection được duy trì lâu dài. | Mỗi lần polling thường tạo một HTTP request riêng. |
| Tự động reconnect | Có sẵn trong EventSource. | Thường phải tự triển khai logic reconnect. | Không cần reconnect theo nghĩa duy trì connection, client chỉ gửi request tiếp theo. |
| Khôi phục event | Có thể hỗ trợ qua id và Last-Event-ID. | Không có cơ chế tương đương được chuẩn hóa trong WebSocket. | Thường phải tự xác định dữ liệu nào đã được nhận. |
| Dữ liệu dạng text | Phù hợp. | Phù hợp. | Phù hợp. |
| Dữ liệu nhị phân | Không phải lựa chọn phù hợp. | Hỗ trợ. | Có thể truyền qua HTTP nhưng hiệu quả tùy trường hợp. |
| Độ trễ cập nhật | Thấp, server có thể gửi ngay khi có event. | Rất thấp, hai chiều liên tục. | Phụ thuộc vào khoảng thời gian giữa các lần polling. |
| Tải request | Không cần request mới cho từng event. | Không cần request mới cho từng message. | Có thể tạo nhiều request không cần thiết khi dữ liệu chưa thay đổi. |
| API phía trình duyệt | EventSource. | WebSocket. | fetch(), XMLHttpRequest hoặc thư viện HTTP. |
| Triển khai phía client | Tương đối đơn giản. | Phức tạp hơn SSE khi cần quản lý connection, reconnect và trạng thái. | Đơn giản. |
| Khả năng mở rộng | Cần quản lý nhiều HTTP connection dài hạn. | Cần quản lý nhiều connection dài hạn và hạ tầng WebSocket. | Có thể tạo nhiều request khi số lượng client lớn. |
| Phù hợp với | Notification, live dashboard, live feed, AI streaming, tiến độ tác vụ. | Chat realtime, game, cộng tác trực tuyến, giao tiếp hai chiều. | Dữ liệu ít thay đổi hoặc hệ thống đơn giản. |
| Điểm hạn chế chính | Chỉ truyền một chiều. | Cần hạ tầng và logic quản lý phức tạp hơn. | Tạo request định kỳ, có thể gây dư thừa. |
Sự kết hợp giữa SSE với các công nghệ khác
SSE thường không hoạt động độc lập mà có thể kết hợp với REST API, WebSocket, Redis Pub/Sub, message queue hoặc AI API để xây dựng hệ thống realtime hoàn chỉnh. Mỗi công nghệ đảm nhiệm một vai trò khác nhau: REST API xử lý request - response, SSE truyền dữ liệu từ server đến client, còn các hệ thống trung gian giúp phân phối và xử lý sự kiện ở quy mô lớn.
- SSE + REST API: SSE và REST API có thể kết hợp để tách rõ hai loại giao tiếp trong cùng một website. REST API đảm nhiệm các thao tác như tạo, cập nhật, xóa hoặc truy vấn dữ liệu, trong khi SSE duy trì một luồng kết nối để server chủ động thông báo cho client khi dữ liệu thay đổi. Ví dụ, trong hệ thống quản lý đơn hàng, client có thể dùng REST API để tạo đơn và lấy thông tin chi tiết. Sau khi đơn hàng được cập nhật trạng thái, server gửi sự kiện qua SSE để giao diện tự động hiển thị trạng thái mới mà không cần liên tục gọi API để kiểm tra.
- SSE + WebSocket: SSE và WebSocket có thể được sử dụng đồng thời khi hệ thống vừa cần server chủ động gửi dữ liệu, vừa cần giao tiếp hai chiều. SSE phù hợp với các luồng thông tin chủ yếu đi từ server đến client, còn WebSocket đảm nhiệm những tương tác cần client gửi dữ liệu liên tục về server. Chẳng hạn, một nền tảng có thể sử dụng WebSocket cho chức năng chat và SSE để gửi thông báo hệ thống, trạng thái xử lý hoặc các sự kiện realtime khác. Cách phân tách này giúp mỗi giao thức đảm nhiệm đúng loại dữ liệu thay vì buộc toàn bộ hệ thống phải sử dụng WebSocket.
- SSE + Redis Pub/Sub: Redis Pub/Sub có thể đóng vai trò trung gian phân phối sự kiện giữa các server. Khi một sự kiện xảy ra, backend có thể publish thông điệp lên Redis, sau đó các server đang subscribe nhận thông điệp và gửi tiếp đến những client SSE phù hợp. Mô hình này đặc biệt hữu ích khi website chạy nhiều instance backend. Nếu client kết nối SSE với server A nhưng sự kiện lại được tạo ra tại server B, Redis Pub/Sub giúp phân phối thông tin giữa các instance để server A vẫn có thể gửi sự kiện đến client.
- SSE + Message Queue: Message queue như RabbitMQ hoặc Kafka có thể kết hợp với SSE khi hệ thống cần xử lý lượng lớn sự kiện hoặc các tác vụ bất đồng bộ. Message queue chịu trách nhiệm lưu trữ, phân phối và điều phối message giữa các thành phần backend, trong khi SSE đảm nhiệm bước cuối là đưa dữ liệu đến trình duyệt. Ví dụ, khi người dùng tải lên một tệp lớn, hệ thống có thể đưa tác vụ vào queue để worker xử lý. Trong quá trình xử lý, backend phát sinh các sự kiện về tiến độ và gửi chúng qua SSE để giao diện hiển thị trạng thái như 10%, 50% hoặc 100%.
- SSE + AI API: SSE đặc biệt phù hợp khi kết hợp với AI API có khả năng streaming. Thay vì chờ mô hình tạo xong toàn bộ câu trả lời, backend có thể nhận từng phần nội dung từ AI API rồi chuyển tiếp các phần dữ liệu đó đến trình duyệt thông qua SSE. Ví dụ, khi người dùng gửi một câu hỏi cho chatbot, backend gọi AI API và nhận về các token hoặc đoạn nội dung được tạo dần theo thời gian. Công nghệ Server-Sent Events lập tức chuyển những phần này đến frontend, giúp câu trả lời xuất hiện từng đoạn trên màn hình thay vì phải chờ toàn bộ nội dung được tạo xong.

Những câu hỏi thường gặp về công nghệ Server-Sent Events
Server-Sent Events là cơ chế truyền dữ liệu realtime từ server đến client thông qua kết nối HTTP duy trì liên tục. Dưới đây là những câu hỏi thường gặp giúp làm rõ cách SSE giao tiếp, khả năng tương thích, xử lý dữ liệu, khôi phục kết nối và mở rộng hệ thống.
1. SSE có phải là công nghệ giao tiếp hai chiều giữa client và server không?
Không. Công nghệ SSE chỉ hỗ trợ truyền dữ liệu một chiều từ server đến client. Client có thể mở kết nối và nhận các sự kiện do server gửi xuống, nhưng không thể sử dụng chính kết nối SSE để gửi dữ liệu ngược lại server. Nếu cần giao tiếp hai chiều realtime, WebSocket thường phù hợp hơn; trong nhiều hệ thống, SSE cũng có thể kết hợp với REST API để client gửi request và SSE để server trả về các cập nhật realtime.
2. Công nghệ SSE có hỗ trợ tất cả các trình duyệt hiện đại không?
Công nghệ Server-Sent Events được hỗ trợ bởi hầu hết các trình duyệt hiện đại và có thể sử dụng thông qua EventSource API. Tuy nhiên, khả năng hỗ trợ có thể khác nhau tùy trình duyệt, phiên bản và môi trường chạy ứng dụng. Với những hệ thống cần hỗ trợ trình duyệt hoặc môi trường đặc thù, nên kiểm tra compatibility trước khi triển khai và chuẩn bị phương án thay thế nếu cần.
3. Có thể gửi dữ liệu dạng nhị phân (Binary/File) qua SSE được không?
SSE được thiết kế để truyền dữ liệu dạng text thông qua MIME type text/event-stream, nên không hỗ trợ binary theo cơ chế truyền dữ liệu gốc như WebSocket. Nếu cần truyền file, hình ảnh hoặc dữ liệu nhị phân lớn, website nên sử dụng HTTP hoặc các cơ chế truyền phù hợp khác. SSE vẫn có thể gửi URL, mã định danh hoặc thông tin mô tả để client biết file nào cần tải về.
4. SSE có thể kết hợp với REST API trong cùng một website không?
Có. SSE và REST API có thể được sử dụng đồng thời vì mỗi công nghệ đảm nhiệm một loại giao tiếp khác nhau. REST API phù hợp với các thao tác request–response như tạo, cập nhật, xóa và truy vấn dữ liệu, trong khi SSE duy trì luồng kết nối để server chủ động gửi thông báo khi dữ liệu thay đổi. Ví dụ, client dùng REST API để tạo đơn hàng và nhận thông tin ban đầu, sau đó nhận các cập nhật trạng thái đơn hàng qua SSE.
5. Xử lý như thế nào khi kết nối SSE bị ngắt giữa chừng? Có bị mất dữ liệu không?
Khi kết nối SSE bị ngắt, EventSource có cơ chế tự động thử kết nối lại sau một khoảng thời gian. Server có thể sử dụng trường id cho từng event, để khi client kết nối lại, thông tin Last-Event-ID giúp server xác định event cuối cùng mà client đã nhận. Tuy nhiên, cơ chế này không tự động đảm bảo dữ liệu không bị mất. Nếu muốn khôi phục các event bị bỏ lỡ, server cần lưu lại lịch sử event trong một khoảng thời gian phù hợp và có cơ chế gửi lại dữ liệu từ vị trí mà client chưa nhận được.
6. Làm thế nào để mở rộng hệ thống SSE cho hàng nghìn kết nối đồng thời trên website?
Để xử lý hàng nghìn kết nối SSE, hệ thống cần thiết kế backend và hạ tầng theo hướng hỗ trợ các kết nối HTTP dài hạn. Server cần kiểm soát số lượng kết nối, bộ nhớ, file descriptor, timeout và cơ chế heartbeat, đồng thời cấu hình reverse proxy hoặc load balancer để tránh buffering và ngắt kết nối không cần thiết. Khi có nhiều server chạy song song, Redis Pub/Sub hoặc message queue có thể được sử dụng để phân phối event giữa các instance trước khi gửi đến client SSE. Ngoài ra, cần theo dõi số lượng kết nối và mức sử dụng tài nguyên để chủ động mở rộng khi lưu lượng tăng.

Qua bài viết của Phương Nam Vina, có thể thấy Server-Sent Events là công nghệ hỗ trợ truyền dữ liệu realtime một chiều từ server đến client thông qua kết nối HTTP liên tục. Với cơ chế tự động kết nối lại, hỗ trợ Last-Event-ID và cách triển khai tương đối đơn giản, SSE phù hợp với các hệ thống cần cập nhật liên tục như thông báo, dashboard, tiến trình xử lý và AI streaming. Tuy nhiên, SSE không phải lựa chọn cho mọi bài toán realtime. Khi hệ thống cần giao tiếp hai chiều, truyền dữ liệu nhị phân hoặc xử lý lượng kết nối rất lớn, cần cân nhắc thêm WebSocket, message queue, Redis Pub/Sub và các giải pháp phù hợp khác. Lựa chọn công nghệ nên dựa trên mô hình giao tiếp, loại dữ liệu, yêu cầu realtime và kiến trúc tổng thể của website.
Tham khảo thêm:
Authentication là gì? Các loại authentication phổ biến
