2014-07-03 22 views
14

Tôi đang làm việc trên một dự án sử dụng Server-Sent-Events và vừa mới chạy vào một điều thú vị: mất kết nối được xử lý khác nhau giữa Chrome và Firefox.Nguồn sự kiện (SSE) có phải cố gắng kết nối lại vô thời hạn không?

Trên Chrome 35 hoặc Opera 22, nếu bạn mất kết nối với máy chủ, nó sẽ cố gắng kết nối lại vô thời hạn vài giây một lần cho đến khi thành công. Trên Firefox 30, mặt khác, nó sẽ chỉ thử một lần và sau đó bạn phải làm mới trang hoặc xử lý sự kiện lỗi được nâng lên và kết nối lại theo cách thủ công.

Tôi thích cách Chrome hoặc Opera thực hiện, nhưng đọc http://www.w3.org/TR/2012/WD-eventsource-20120426/#processing-model, có vẻ như một khi EventSource cố gắng kết nối lại và không thành công do lỗi mạng hoặc lỗi khác, nó không nên thử lại kết nối. Tuy nhiên, tôi không chắc chắn liệu tôi có hiểu được thông số chính xác hay không.

Tôi đã đặt yêu cầu Firefox cho người dùng, chủ yếu dựa trên thực tế là bạn không thể có nhiều tab với luồng sự kiện từ cùng một URL đang mở trên Chrome, nhưng phát hiện mới này có thể là vấn đề. Mặc dù, nếu Firefox hoạt động theo spec thì tôi cũng có thể làm việc xung quanh nó bằng cách nào đó.

Edit:

Tôi sẽ tiếp tục nhắm mục tiêu Firefox cho bây giờ. Đây là cách tôi xử lý reconnections:

var es = null; 
function initES() { 
    if (es == null || es.readyState == 2) { // this is probably not necessary. 
     es = new EventSource('/push'); 
     es.onerror = function(e) { 
      if (es.readyState == 2) { 
       setTimeout(initES, 5000); 
      } 
     }; 
     //all event listeners should go here. 
    } 
} 
initES(); 

Trả lời

3

tôi đọc tiêu chuẩn theo cùng một cách như bạn nhưng, ngay cả khi không có lỗi trình duyệt để xem xét, lỗi mạng, máy chủ mà chết nhưng giữ ổ cắm mở, vv Vì vậy, tôi thường thêm một phần còn lại trên đầu trang của kết nối lại mà SSE cung cấp.

Trên client-side tôi làm điều đó với một vài globals và một hàm helper:

var keepaliveSecs = 20; 
var keepaliveTimer = null; 

function gotActivity(){ 
if(keepaliveTimer != null)clearTimeout(keepaliveTimer); 
keepaliveTimer = setTimeout(connect,keepaliveSecs * 1000); 
} 

Sau đó, tôi gọi gotActivity() ở đầu connect(), và sau đó mỗi khi tôi nhận được một tin nhắn. (connect() về cơ bản chỉ cần gọi tới new EventSource())

Ở phía máy chủ, nó có thể nhổ ra dấu thời gian (hoặc thứ gì đó) sau mỗi 15 giây, trên luồng dữ liệu bình thường hoặc sử dụng bộ hẹn giờ và nhổ ra dấu thời gian (hoặc thứ gì đó) nếu luồng dữ liệu bình thường trở nên yên lặng trong 15 giây.

1

Điều tôi đã nhận thấy (trong Chrome ít nhất) là khi bạn đóng kết nối SSE bằng chức năng close(), nó sẽ không cố gắng kết nối lại.

var sse = new EventSource("..."); 
sse.onerror = function() { 
    sse.close(); 
}; 
Các vấn đề liên quan