2012-03-29 7 views
8

Ich habe Push-Benachrichtigungen in meiner JavaScript-Client-App mit EventSource. Ich kann Ereignis-Listener wie folgt anhängen:HTML5-EventSource-Listener für alle Ereignisse?

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

Aber ich will alle Ereignisse überwachen, die (im Grunde für das Debuggen) vom Server geschoben werden, so dass, wenn ein Ereignis gesendet wird, aber es hat keine Zuhörer Ereignis kann ich leicht finden. Ich meine, ich möchte nicht nur alle Ereignisse "ignorieren", bei denen keine eventListener gebunden sind.

Ich würde erwarten, so etwas zu tun:

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

Aber die Spezifikation und Tutorials wie das bei html5rocks nicht angeben, ob dies möglich ist oder nicht.

Auf der anderen Seite kann es einige Firefox/Chrome-Erweiterung sein, die alle Serverereignisse oder etwas überwachen können. Diese Dinge würden wirklich helfen, Push-Benachrichtigungen zu entwickeln.

Danke!

Antwort

23

Ich selbst finde eine Lösung, die auch die EventSource-Schnittstelle enorm verbessert.

Serverseite: Senden Sie nicht den Ereignistyp, sondern nur ein zusätzliches Datenfeld (mit dem ich immer json). Also statt

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

Ich sende diese vom Server statt:

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

Client-Seite: Jetzt kann ich Eventsource onmessage Rückruf ist, dass auf jede Nachricht gefeuert, die kein Ereignis haben Art.

Und für Ereignislistener binden ich eine Wrapper-Klasse mit Backbone.Event-Funktionalität. Das Ergebnis:

// 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; 
})(); 

Jetzt mit dieser Wrapper-Klasse, ich kann die Funktionalität leicht erweitern, schickten alle Serverereignisse können leicht das Ereignis in dieser Klasse Handhabung fast zu einem Backbone.Events überwacht und dank ist viel mächtiger.

Anwendungsbeispiel:

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'); 

Jetzt habe ich eine Komponente, die leicht zu handhaben ist, zu erweitern, Debug- und Test.

+12

„onMessage Rückruf bei jeder Nachricht ausgelöst wird, die ** kein Ereignis hat Art**". Das war eine sehr nützliche Information für mich. Vielen Dank. –

+0

Nur ein fyi: Aufruf von 'onmessage = some_function;' ist genau das gleiche wie Aufruf von 'addEventListener (" message ", some_function);'. Dies macht deutlich, dass Nachrichten ohne Ereignistyp mit Nachrichten mit dem Ereignistyp "Nachricht" übereinstimmen. – Ashitaka

+0

Hallo Tothemario. Aus irgendeinem Grund funktioniert JSON.parse (event.data) nicht für mich. Sind Sie so freundlich, Ihren serverseitigen Weg zur Datengenerierung zu bieten: {mykey: 'myvalue', eventName: 'eventName'}? Danke im Voraus. – 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

Dies funktioniert nicht, da 'onmessage' nur Ereignisse ohne den Typ https://developer.mozilla.org/ru/docs/Web/API/EventSource behandelt – Grief

0

Ich weiß, dass dies nicht ein Eventsource ist, aber ich war für die gleiche Sache suchen (eine Art und Weise alle eingehenden Ereignisse zu fangen, ohne ihre Art zu wissen). Ohne Kontrolle über den Server diese Ereignisse zu senden, landete ich es nur mit einem XHR schreiben, falls jemand kommt sonst über diese:

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); 
});