Frage

Ich habe einige Beiträge zu diesem Thema lesen und die Antworten sind Kometen, Reverse Ajax, HTTP-Streaming, Push-Server, etc.

Wie eingehende E-Mail-Benachrichtigung bei Google Mail funktioniert?

Wie ist GMail Chat Lage AJAX-Anforderungen ohne Client-Interaktion zu machen?

Ich würde gerne wissen, ob es irgendwelche Codereferenzen sind, die ich folgen kann ein ganz einfaches Beispiel zu schreiben. Viele Beiträge oder Webseiten sprechen nur über die Technologie. Es ist schwer, eine vollständige Beispielcode zu finden. Auch scheint es viele Methoden können verwendet werden, um die Kometen zu implementieren, z.B. Versteckte IFrame, XMLHttpRequest. Meiner Meinung nach ist XMLHttpRequest verwendet, ist eine bessere Wahl. Was denken Sie über die Vor- und Nachteile der verschiedenen Methoden? Welches ist Google Mail verwenden?

Ich weiß, sie braucht es sowohl in Server-Seite und Client-Seite zu tun. Gibt es einen PHP und Javascript Beispielcode?

War es hilfreich?

Lösung

Die Art und Weise Book tut, ist ziemlich interessant.

Ein gemeinsames Verfahren zur Herstellung solcher Mitteilungen machen, ist ein Skript auf dem Server abzufragen (unter Verwendung von AJAX) auf einem bestimmten Intervall (vielleicht alle paar Sekunden), um zu überprüfen, ob etwas passiert ist. Dies kann jedoch ziemlich Netzwerk intensiv sein, und Sie oft sinnlose Anfragen machen, weil nichts passiert ist.

Die Art und Weise Facebook macht es den Kometen Ansatz nutzt, anstatt Polling auf einem Intervall, sobald eine Umfrage abgeschlossen ist, gibt es ein anderes. Jedoch hat jede Anforderung an das Skript auf dem Server eine extrem lange Timeout, und der Server antwortet nur auf die Anforderung einmal etwas passiert ist. Diesen Vorgang können Sie sehen, ob Sie Firebug Registerkarte Konsole, während auf Facebook bringen, mit Anfragen an ein Skript möglicherweise Protokollführung. Es ist ganz wirklich genial, da diese Methode sofort verkürzt sich sowohl die Anzahl der Anfragen, und wie oft Sie haben sie zu senden. Sie haben effektiv jetzt ein Ereignis Rahmen, um den Server zu ‚Feuer‘ Ereignisse ermöglicht.

Dahinter kehrte in Bezug auf den tatsächlichen Inhalt von diesen Umfragen, es ist eine JSON-Antwort, mit dem, was erscheint eine Liste der Ereignisse zu sein und Informationen über sie. Es minimiert aber, so ist ein bisschen schwer zu lesen.

Im Hinblick auf die aktuelle Technologie ist AJAX der Weg hier zu gehen, weil Sie Anfrage Timeouts steuern kann, und viele andere Dinge. Ich würde empfehlen, (Stack-Überlauf Klischee hier) jQuery mit der AJAX zu tun, ist es weg viele der Quer compability Probleme nehmen werde. In Bezug auf den PHP, können Sie einfach eine Ereignisprotokoll-Datenbank-Tabelle in Ihrem PHP-Skript abzufragen, und geben nur an den Client, wenn etwas passiert? Es gibt, erwarte ich, viele Möglichkeiten, dies umzusetzen.

Die Implementierung:

Server-Seite:

Es erscheint einige Implementierungen von Kometen Bibliotheken in PHP zu sein, aber um ehrlich zu sein, es ist wirklich sehr einfach, etwas vielleicht wie der folgenden Pseudo-Code:

while(!has_event_happened()) {
   sleep(5);
}

echo json_encode(get_events());
  • Die has_event_happened Funktion würde nur überprüfen, ob alles in einer Ereignistabelle oder etwas geschehen war, und dann würde die get_events Funktion, um eine Liste der neuen Zeilen in der Tabelle zurückkehren? Hängt vom Kontext des Problems wirklich.

  • Vergessen Sie nicht, Ihre PHP max Ausführungszeit zu ändern, sonst wird es Timeout früh!

Client-Seite:

Werfen Sie einen Blick auf die jQuery-Plugin zu tun Comet Interaktion:

Wie gesagt, scheint das Plugin ein gutes Stück von Komplexität hinzuzufügen, es ist wirklich sehr einfach auf dem Client, vielleicht (mit jQuery) so etwas wie:

function doPoll() {
   $.get("events.php", {}, function(result) {
      $.each(result.events, function(event) { //iterate over the events
          //do something with your event
      });
      doPoll(); 
      //this effectively causes the poll to run again as
      //soon as the response comes back
   }, 'json'); 
}

$(document).ready(function() {
    $.ajaxSetup({
       timeout: 1000*60//set a global AJAX timeout of a minute
    });
    doPoll(); // do the first poll
});

Das Ganze hängt viel, wie Sie Ihre bestehende Architektur zusammengesetzt ist.

Andere Tipps

Update

Wie ich weiter daran empfangen upvotes, ich denke, es vernünftig ist, sich daran zu erinnern, dass diese Antwort ist 4 Jahre alt. Web hat sich in einem sehr schnellen Tempo gewachsen, so wenden Sie sich bitte über diese Antwort achtsam sein.


Ich hatte das gleiche Problem vor kurzem und über das Thema erforschen.

Die Lösung gegeben wird lange Polling genannt, und es richtig verwenden Sie müssen sicher sein, dass Ihre AJAX-Anforderung ein „großen“ Timeout hat und immer diesen Antrag zu stellen, nachdem die aktuellen Ende (Timeout, Fehler oder Erfolg).

Long Polling - Client

Hier zu halten Code kurz gesagt, werde ich jQuery verwenden:

function pollTask() { 

    $.ajax({

        url: '/api/Polling',
        async: true,            // by default, it's async, but...
        dataType: 'json',       // or the dataType you are working with
        timeout: 10000,          // IMPORTANT! this is a 10 seconds timeout
        cache: false

    }).done(function (eventList) {  

       // Handle your data here
       var data;
       for (var eventName in eventList) {

            data = eventList[eventName];
            dispatcher.handle(eventName, data); // handle the `eventName` with `data`

       }

    }).always(pollTask);

}

Es ist wichtig zu erinnern, dass (von jQuery docs ):

  

In jQuery 1.4.x und unten wird das XMLHttpRequest-Objekt in einem sein   ungültiger Zustand, wenn die Anforderung Timeout; Zugriff auf alle Objektelemente   kann eine Ausnahme werfen. In Firefox 3.0+ nur, Skript und JSONP   Diese kann nicht durch einen Timeout abgebrochen werden; das Skript ausgeführt werden soll, auch wenn   es kommt nach der Timeout-Zeit.

Long Polling - Server

Es ist nicht in einer bestimmten Sprache, aber es wäre so etwas wie dies:

function handleRequest () {  

     while (!anythingHappened() || hasTimedOut()) { sleep(2); }

     return events();

} 

Hier finden hasTimedOut sicherstellen, dass Ihr Code nicht ewig warten, und anythingHappened, wird geprüft, ob ein Ereignis passiert. Die sleep ist für die Freigabe des Thread andere Dinge zu tun, während es passiert nichts. Die events wird ein Wörterbuch der Ereignisse zurückgeben (oder eine andere Datenstruktur können Sie es vorziehen) im JSON-Format (oder jede andere Sie bevorzugen).

Es löst sicherlich das Problem, aber, wenn Sie über die Skalierbarkeit und Performance angeht, wie ich bei der Recherche, Sie eine andere Lösung überlegen könnte ich gefunden.

Lösung

Verwenden Sie Steckdosen!

Auf Client-Seite, um Kompatibilitätsprobleme zu vermeiden, verwenden Sie socket.io . Es wird versucht Buchse direkt zu verwenden, und hat Fallbacks zu anderen Lösungen, wenn Steckdosen nicht verfügbar sind.

Auf Server-Seite, erstellen Sie einen Server NodeJS (zB hier ). Der Kunde wird auf diesen Kanal (Beobachter) Registrierung mit dem Server erstellt. Jedes Mal, wenn eine Benachrichtigung gesendet werden muss, wird es in diesem Kanal und der subscriptor (Client) veröffentlicht informiert wird.

Wenn Sie diese Lösung nicht gefällt, versuchen APE ( Ajax-Push-Maschine ).

Hope I geholfen.

Nach einer Diashow über Facebook Messaging System nutzt Facebook die Komet-Technologie „Push“ Nachricht an Web-Browsern. Facebook Komet-Server auf dem Open Source Erlang Webserver mochiweb gebaut.

Im Bild unten, der Ausdruck „Kanal-Cluster“ bedeutet „Komet-Server“.

Systemübersicht

Viele andere große Websites ihre eigenen Kometen Server bauen, weil es Unterschiede gibt zwischen jedem Bedarf des Unternehmens. Aber bauen Sie Ihren eigenen Komet-Server auf einem Open-Source-Komet-Server ist ein guter Ansatz.

Sie können versuchen, icomet , ein ++ C1000K C Komet Server mit libevent gebaut. icomet bietet auch eine JavaScript-Bibliothek, es einfach ist, so einfach zu bedienen wie:

var comet = new iComet({
    sign_url: 'http://' + app_host + '/sign?obj=' + obj,
    sub_url: 'http://' + icomet_host + '/sub',
    callback: function(msg){
        // on server push
        alert(msg.content);
    }
});

icomet unterstützt eine breite Palette von Browser und Betriebssysteme, einschließlich Safari (iOS, Mac), IEs (Windows), Firefox, Chrome, etc.

Facebook verwendet MQTT anstelle von HTTP. Push ist besser als Polling. Durch HTTP müssen wir den Server kontinuierlich abzufragen, sondern über MQTT Server schiebt die Nachricht an Kunden.

Vergleich zwischen MQTT und HTTP: http://www.youtube.com/watch?v = -KNPXPmx88E

. Hinweis: meine Antworten am besten passt für mobile Geräte

Ein wichtiges Problem mit langen Polling ist die Fehlerbehandlung. Es gibt zwei Arten von Fehlern:

  1. Die Anfrage kann in der Timeout Fall der Client die Verbindung sofort wieder herstellen soll. Dies ist ein normales Ereignis in Lang-Abfrage, wenn keine Nachrichten eingetroffen sind.

  2. Ein Netzwerkfehler oder ein Fehler bei der Ausführung. Dies ist ein tatsächlicher Fehler, die der Kunde ordnungsgemäß akzeptieren sollte und warten, bis der Server on-line zu kommen.

Das Hauptproblem ist, dass, wenn Ihre Fehlerbehandlungsroutine die Verbindung sofort auch für einen Typ-2-Fehler wieder herstellt, die Kunden würden DOS der Server.

Beide Antworten mit Codebeispiel, verpassen Sie diese.

function longPoll() { 
        var shouldDelay = false;

        $.ajax({
            url: 'poll.php',
            async: true,            // by default, it's async, but...
            dataType: 'json',       // or the dataType you are working with
            timeout: 10000,          // IMPORTANT! this is a 10 seconds timeout
            cache: false

        }).done(function (data, textStatus, jqXHR) {
             // do something with data...

        }).fail(function (jqXHR, textStatus, errorThrown ) {
            shouldDelay = textStatus !== "timeout";

        }).always(function() {
            // in case of network error. throttle otherwise we DOS ourselves. If it was a timeout, its normal operation. go again.
            var delay = shouldDelay ? 10000: 0;
            window.setTimeout(longPoll, delay);
        });
}
longPoll(); //fire first handler
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top