Tóm Tắt
Tại sao dùng Server-sent Events (SSE)
SSE tạo ra liên kết một chiều từ server đến client sử dụng giao thức HTTP truyền thống cuội nguồn với định nghĩa dữ liệu đơn thuần cho phía server ( sự kiện stream format ) và API gọn nhẹ phía client .So với giải pháp polling từ client lên server để kiểm tra tài liệu thì SSE hiệu suất cao hơn rất nhiều do client chỉ cần tạo liên kết HTTP lên server một lần, và server giữ liên kết đó để liên tục gửi data cho client .
WebSockets thì phức tạp và hoành tráng hơn hẳn SSE. Tuy nhiên WebSockets là kết nối hai chiều mà đôi khi ta lại không cần chiều từ client lên server. Ngoài ra WebSockets là một giao thức hoàn toàn khác và đòi hỏi server phải hỗ trợ (Điểm này thì Node.js là số 1, PHP thì cần thêm thư viện ví dụ Ratchet PHP WebSockets).
Định dạng dữ liệu của Server-sent Events
Phía server phải tuân thủ in dữ liệu theo format của text/event-stream
như sau:
Prefix | Kiểu | Mô tả |
---|---|---|
data: | string |
Dữ liệu là một chuỗi ký tự kết thúc bằng hai ký tự xuống dòng \n\n .Ví dụ: data: This is a message\n\n
Nếu muốn chuỗi dữ liệu có nhiều dòng thì ta có thể dùng nhiều dòng Ví dụ: Phía client sẽ nhận được chuỗi SSE không có cấu trúc object nhưng bạn có thể thay bằng chuỗi JSON và phía client dùng |
id: | string |
Thông báo cho phía client EventSource biết được sự kiện cuối cùng trong trường hợp mất kết nối.
Khi EventSource thiết lập lại kết nối sẽ gửi lên server một HTTP header là Ví dụ: Phía client EventSource cũng có thể lấy giá trị id này qua |
event: | string |
Chỉ định tên sự kiện sẽ được EventSource kích hoạt bằng EventSource.addEventListener(eventName, callback) .
Ví dụ: Ta đón sự kiện
Chú ý dữ liệu của |
retry: | integer |
Khi bị ngắt kết nối do timeout (không có dữ liệu mới sau một thời gian) hoặc máy chủ trả về HTTP code 200, EventSource sẽ đợi một khoảng thời gian retry (milliseconds) trước khi kết nối lại từ đầu.
Nếu không chỉ định |
Mã nguồn tạo kết nối và nhận dữ liệu Server-sent Events phía client (JavaScript)
Bộ khung khai báo cơ bản phía client browser bằng JavaScript như sau :
if ( !!window.EventSource ) { // Pass the URL of the event stream to subscribe, // it might be relative or absolute var source = new EventSource( "sse.php" ); source.onopen = function(e) { console.log("SSE connection was established."); }; source.onerror = function(e) { console.error("SSE error:", e); } // handle incoming data source.onmessage = function(e) { console.log("SSE data received:", e.id, e.data); }; // custom events source.addEventListener("bigdata", function(e) { // TODO some specific processing goes here console.log("SSE event received:", e.data); }, false); } else { console.error( "Your web browser does not support SSE" ); }
Lưu ý khi dùng Server-sent Events
CORS
EvenSource cũng như các HTTP request thông thường từ client đều nhạy cảm với CORS. Server phải cùng domain với script hoặc gửi header Access-Control-Allow-Origin
để cho phép domain chứa script.
Server phải giữ kết nối
Phía server nếu không giữ kết nối (ví dụ bằng event loop) mà chỉ đơn thuần trả ít dữ liệu rồi exit (Code 200) thì Server-sent Events sẽ tìm cách kết nối lại liên tục và hành xử chẳng khác gì polling – hoàn toàn không đúng với tinh thần thiết kế của SSE.
Xem thêm: Nghịch lý Web 3.0
Đóng kết nối Server-sent Events từ phía client
Để đóng kết nối từ phía JavaScript client, chúng ta sử dụng hàm source.close()
.
Nếu bạn không thực thi đóng liên kết EventSource, trình duyệt khi không thấy có tài liệu mới sau một thời hạn sẽ tự hiểu là bị connection timeout và liên kết lại với server từ đầu .
Yêu cầu đóng kết nối Server-sent Events từ phía server
Phía server có thể chủ động yêu cầu ngừng kết nối này bằng cách gửi một dấu hiệu, ví dụ dùng id:
hoặc tạo một sự kiện tùy chỉnh với event:
để client biết mà gọi source.close()
.
Ví dụ server gửi chuỗi :
id: close\n data: \n\n
Đoạn mã phía client :
source.onmessage = function(e) { if (e.lastEventId === 'close') source.close(); else console.log(e.data); };
Một cách ứng dụng SSE đó là thực thi giải quyết và xử lý một phức tạp trên server trong vẫn khi trả về thông tin real-time về client, tìm hiểu thêm tại ĐÂY .
Source: https://final-blade.com
Category : Tiền Điện Tử – Tiền Ảo