2012-03-29 32 views
8

Tôi có thông báo đẩy trong ứng dụng khách JavaScript của tôi bằng EventSource. Tôi có thể đính kèm nghe sự kiện như thế này:HTML5 EventSource listener cho tất cả các sự kiện?

source.addEventListener('my_custom_event_type', function(e) { 
    console.log(e.data); 
}, false); 

Nhưng tôi muốn theo dõi tất cả các sự kiện đang được đẩy từ máy chủ (về cơ bản để gỡ lỗi), vì vậy nếu một số sự kiện được gửi nhưng nó không có lắng nghe sự kiện tôi có thể dễ dàng tìm thấy nó. Ý tôi là, tôi không muốn chỉ "phớt lờ" tất cả các sự kiện mà không có eventListeners nào bị ràng buộc.

tôi mong chờ để làm một cái gì đó như thế này:

source.addEventListener('*', function(e) { 
    console.debug('Event with no listener attached: ', e); 
}, false); 

Nhưng đặc điểm kỹ thuật và hướng dẫn như tại html5rocks không chỉ định nếu điều này là có thể hay không.

Mặt khác, nó có thể là một số phần mở rộng firefox/chrome cho phép giám sát tất cả các sự kiện máy chủ hoặc một cái gì đó. Những thứ đó thực sự sẽ giúp phát triển các thông báo đẩy.

Cảm ơn!

Trả lời

23

Tôi tự mình tìm ra giải pháp, điều đó cũng cải thiện rất nhiều giao diện EventSource.

Phía máy chủ: Không gửi loại sự kiện, chỉ cần bao gồm trường dữ liệu bổ sung (khi đó tôi luôn sử dụng json). Vì vậy, thay vì

event: eventName 
data: {mykey: 'myvalue'} 

Tôi gửi thông điệp này từ máy chủ thay vì:

data: {mykey: 'myvalue', eventName: 'eventName'} 

Khách hàng bên: Bây giờ tôi có thể sử dụng EventSource onmessage gọi lại, đó là bắn vào mọi thông điệp mà không có một sự kiện kiểu.

Và đối với trình nghe sự kiện ràng buộc, tôi tạo một lớp trình bao bọc với chức năng Backbone.Event. Kết quả:

// Server Sent Events (Event Source wrapper class) 
var MyEventSource = (function() { 

    function MyEventSource(url) { 
    var self = this; 
    _.extend(this, Backbone.Events); 

    this.source = new EventSource(url); 
    this.source.onmessage = function(event) { 
     var data, eventName; 
     var data = JSON.parse(event.data); 
     var eventName = data.eventName; delete data.eventName; 

     // Now we can monitor all server sent events 
     console.log('app.server.on ', eventName, '. Data: ', data); 

     self.trigger(eventName, data); 
    }; 
    } 

    return MyEventSource; 
})(); 

Bây giờ với lớp wrapper này, tôi có thể dễ dàng mở rộng chức năng, tất cả các máy chủ gửi các sự kiện có thể dễ dàng theo dõi và nhờ Backbone.Events mở rộng xử lý sự kiện trong lớp này là mạnh hơn rất nhiều.

Cách sử dụng Ví dụ:

var source = new MyEventSource('url/of/source'); 

// Add event listener 
source.on('eventName', function(data) { 
    console.log(data); 
}); 

// Fire a event (also very useful for testing and debugging!!) 
source.trigger('eventName', { mykey: 'myvalue' }); 

// Unbind event listener (very important for complex applications) 
source.off('eventName'); 

Bây giờ tôi có một thành phần đó là dễ dàng để xử lý, gia hạn, sửa lỗi và thử nghiệm.

+12

"Onmessage callback được kích hoạt trên mọi thông báo ** không có sự kiện kiểu**". Đó là thông tin hữu ích cho tôi. Cảm ơn. –

+0

Chỉ cần một fyi: gọi 'onmessage = some_function;' là chính xác giống như gọi 'addEventListener (" message ", some_function);'. Điều này làm cho nó rõ ràng rằng các tin nhắn mà không có một loại sự kiện là giống như tin nhắn với một loại sự kiện của "tin nhắn". – Ashitaka

+0

Xin chào tothemario. Vì một số lý do, JSON.parse (event.data) không hoạt động đối với tôi. Bạn có thể tử tế như vậy để cung cấp cách phía máy chủ của bạn để tạo dữ liệu: {mykey: 'myvalue', eventName: 'eventName'}? Cảm ơn trước. – pouzzler

0
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script> 
    <script> 
    var content = ''; 
    if(typeof(EventSource)!=="undefined") 
    { 
     var source = new EventSource("demo_sse.php"); 
     source.onmessage = function(event) 
     { 
     content+=event.data + "<br>"; 
     $("#result").html(content); 
     }; 
    } 
    else 
    { 
     $("#result").html("Sorry, your browser does not support server-sent events..."); 
    } 
    </script> 
+1

Điều này sẽ không hoạt động vì 'onmessage' chỉ xử lý các sự kiện không có loại https://developer.mozilla.org/ru/docs/Web/API/EventSource – Grief

0

Tôi biết đây không phải là EventSource, nhưng tôi đang tìm kiếm một điều tương tự (một cách để nắm bắt tất cả các sự kiện đến mà không biết loại của chúng). Nếu không có bất kỳ kiểm soát nào đối với máy chủ gửi những sự kiện này, tôi đã kết thúc bằng cách viết nó với một XHR, trong trường hợp bất kỳ ai khác bắt gặp điều này:

function eventStream(path, callback){ 
    //Create XHR object 
    var xhr = new XMLHttpRequest(); 

    //initialize storage for previously fetched information 
    var fetched=''; 

    //Set readystatechange handler 
    xhr.onreadystatechange=function(){ 

     //If the connection has been made and we have 200, process the data 
     if(xhr.readyState>2 && xhr.status==200){ 
      //save the current response text 
      var newFetched=xhr.responseText; 

      //this is a stream, so responseText always contains everything 
      //from the start of the stream, we only want the latest 
      var lastFetch=xhr.responseText.replace(fetched, ''); 

      //Set the complete response text to be removed next time 
      var fetched=newFetched; 

      //callback to allow parsing of the fetched data 
      callback(lastFetch); 
     } 
    }; 

    //open and send to begin the stream; 
    xhr.open('GET', path, true); 
    xhr.send(); 
} 

parseEvents=function(response){ 
    var events=[]; 
    //split out by line break 
    var lines=response.split("\n"); 

    //loop through the lines 
    for(var i=0;i<lines.length;i++){ 

     //each event consists of 2 lines, one begins with 
     //"name:", the other with "data" 
     //if we hit data, process it and the previous line 
     if(lines[i].substr(0, lines[i].indexOf(':'))=='data'){ 

      //add this event to our list for return 
      events.push({ 

       //get the event name 
       name: lines[i-1].split(':')[1].trim(), 
       //parse the event data 
       data: $.parseJSON(lines[i].substr(lines[i].indexOf(':')+1).trim()) 
      }); 
     } 
    } 
    //return the parsed events 
    return events; 
}; 

evenStream('http://example.com/myEventPath', function(response){ 
    var events=parseEvents(response); 
}); 
Các vấn đề liên quan