Die Art und Weise, wie Facebook dies tut, ist ziemlich interessant.
Eine übliche Methode für solche Benachrichtigungen besteht darin, ein Skript auf dem Server (unter Verwendung von AJAX) in einem bestimmten Intervall (möglicherweise alle paar Sekunden) abzufragen, um zu überprüfen, ob etwas passiert ist. Dies kann jedoch ziemlich netzwerkintensiv sein, und Sie stellen häufig sinnlose Anfragen, da nichts passiert ist.
Bei Facebook wird der Kometenansatz verwendet, anstatt in einem Intervall abzufragen. Sobald eine Umfrage abgeschlossen ist, wird eine andere ausgegeben. Jede Anforderung an das Skript auf dem Server hat jedoch ein extrem langes Zeitlimit, und der Server antwortet auf die Anforderung erst, wenn etwas passiert ist. Sie können dies beobachten, wenn Sie auf Facebook die Registerkarte "Konsole" von Firebug aufrufen und Anfragen an ein Skript möglicherweise Minuten dauern. Es ist wirklich ziemlich genial, da diese Methode sowohl die Anzahl der Anfragen als auch die Häufigkeit, mit der Sie sie senden müssen, sofort reduziert. Sie haben jetzt effektiv ein Ereignis-Framework, mit dem der Server Ereignisse auslösen kann.
Dahinter steht in Bezug auf den tatsächlichen Inhalt, der aus diesen Umfragen zurückgegeben wurde, eine JSON-Antwort mit einer scheinbaren Liste von Ereignissen und Informationen darüber. Es ist zwar verkleinert, daher etwas schwer zu lesen.
In Bezug auf die aktuelle Technologie ist AJAX der richtige Weg, da Sie Anforderungszeitlimits und viele andere Dinge steuern können. Ich würde empfehlen (Stack Overflow-Klischee hier), jQuery für AJAX zu verwenden, da dadurch viele Probleme mit der Kompatibilität behoben werden. In Bezug auf PHP könnten Sie einfach eine Ereignisprotokoll-Datenbanktabelle in Ihrem PHP-Skript abfragen und nur dann zum Client zurückkehren, wenn etwas passiert? Ich gehe davon aus, dass es viele Möglichkeiten gibt, dies umzusetzen.
Implementierung:
Serverseite:
Es scheint einige Implementierungen von Kometenbibliotheken in PHP zu geben, aber um ehrlich zu sein, ist es wirklich sehr einfach, so etwas wie der folgende Pseudocode:
while(!has_event_happened()) {
sleep(5);
}
echo json_encode(get_events());
Die Funktion has_event_happened prüft nur, ob in einer Ereignistabelle oder etwas anderem etwas passiert ist, und die Funktion get_events gibt dann eine Liste der neuen Zeilen in der Tabelle zurück. Kommt wirklich auf den Kontext des Problems an.
Vergessen Sie nicht, die maximale Ausführungszeit von PHP zu ändern, da sonst die Zeit abläuft!
Kundenseite:
Schauen Sie sich das jQuery-Plugin für die Comet-Interaktion an:
Das Plugin scheint jedoch einiges an Komplexität hinzuzufügen. Es ist auf dem Client wirklich sehr einfach, 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 stark davon ab, wie Ihre vorhandene Architektur zusammengesetzt ist.
Aktualisieren
Da ich weiterhin positive Stimmen dazu erhalte, halte ich es für vernünftig, mich daran zu erinnern, dass diese Antwort 4 Jahre alt ist. Das Web ist sehr schnell gewachsen. Bitte beachten Sie diese Antwort.
Ich hatte kürzlich das gleiche Problem und recherchierte über das Thema.
Die angegebene Lösung wird als langes Polling bezeichnet. Um sie korrekt zu verwenden, müssen Sie sicherstellen, dass Ihre AJAX-Anforderung ein "großes" Zeitlimit aufweist, und diese Anforderung immer nach dem Ende des aktuellen Zeitraums (Zeitlimit, Fehler oder Erfolg) stellen.
Lange Umfrage - Client
Um den Code kurz zu halten, verwende ich hier jQuery:
Es ist wichtig, sich daran zu erinnern (aus jQuery-Dokumenten ):
Lange Abfrage - Server
Es ist nicht in einer bestimmten Sprache, aber es wäre ungefähr so:
Hier
hasTimedOut
wird sicherstellen , dass Ihr Code nicht ewig warten, undanythingHappened
wird prüfen , ob jeder Fall geschieht. Dassleep
ist für die Freigabe Ihres Threads, um andere Dinge zu tun, während nichts passiert. Dasevents
gibt ein Wörterbuch mit Ereignissen (oder einer anderen von Ihnen bevorzugten Datenstruktur) im JSON-Format (oder einer anderen von Ihnen bevorzugten) zurück.Es löst sicherlich das Problem, aber wenn Sie sich Sorgen über Skalierbarkeit und Leistung machen, wie ich es bei der Recherche war, könnten Sie eine andere Lösung in Betracht ziehen, die ich gefunden habe.
Lösung
Verwenden Sie Steckdosen!
Verwenden Sie auf der Clientseite socket.io , um Kompatibilitätsprobleme zu vermeiden . Es wird versucht, Sockets direkt zu verwenden und auf andere Lösungen zurückzugreifen, wenn keine Sockets verfügbar sind.
Erstellen Sie auf der Serverseite einen Server mit NodeJS (Beispiel hier ). Der Client abonniert diesen mit dem Server erstellten Kanal (Beobachter). Wann immer eine Benachrichtigung gesendet werden muss, wird sie in diesem Kanal veröffentlicht und der Abonnent (Client) wird benachrichtigt.
Wenn Ihnen diese Lösung nicht gefällt, versuchen Sie es mit APE ( Ajax Push Engine ).
Hoffe ich habe geholfen.
quelle
hasTimedOut()
?Laut einer Diashow über das Messaging-System von Facebook verwendet Facebook die Kometentechnologie, um Nachrichten an Webbrowser zu "pushen". Der Kometenserver von Facebook basiert auf dem Open-Source-Erlang-Webserver Mochiweb.
In der Abbildung unten bedeutet der Ausdruck "Kanalcluster" "Kometenserver".
Viele andere große Websites bauen ihren eigenen Kometenserver, da es Unterschiede zwischen den Anforderungen jedes Unternehmens gibt. Der Aufbau eines eigenen Kometenservers auf einem Open-Source-Kometenserver ist jedoch ein guter Ansatz.
Sie können icomet ausprobieren , einen C1000K C ++ - Kometenserver, der mit libevent erstellt wurde. icomet bietet auch eine JavaScript-Bibliothek, die so einfach zu bedienen ist wie:
icomet unterstützt eine Vielzahl von Browsern und Betriebssystemen, darunter Safari (iOS, Mac), IEs (Windows), Firefox, Chrome usw.
quelle
Facebook verwendet MQTT anstelle von HTTP. Push ist besser als Polling. Über HTTP müssen wir den Server kontinuierlich abfragen, aber über den MQTT-Server wird die Nachricht an die Clients weitergeleitet.
Vergleich zwischen MQTT und HTTP: http://www.youtube.com/watch?v=-KNPXPmx88E
Hinweis: Meine Antworten passen am besten für mobile Geräte.
quelle
Ein wichtiges Problem bei langen Abfragen ist die Fehlerbehandlung. Es gibt zwei Arten von Fehlern:
Die Anforderung kann eine Zeitüberschreitung aufweisen. In diesem Fall sollte der Client die Verbindung sofort wiederherstellen. Dies ist ein normales Ereignis bei langen Abfragen, wenn keine Nachrichten eingegangen sind.
Ein Netzwerkfehler oder ein Ausführungsfehler. Dies ist ein tatsächlicher Fehler, den der Client ordnungsgemäß akzeptieren und warten sollte, bis der Server wieder online ist.
Das Hauptproblem ist, dass die Clients den Server unter DOS ausführen würden, wenn Ihr Fehlerbehandler die Verbindung auch bei einem Fehler vom Typ 2 sofort wieder herstellt.
Beide Antworten mit Codebeispiel verpassen dies.
quelle