Ich habe darüber nachgedacht, Echtzeit-Chat mit einem PHP-Backend zu implementieren, aber ich bin auf diesen Kommentar auf einer Seite gestoßen, in der es um Comet geht:
Mein Verständnis ist, dass PHP eine schreckliche Sprache für Comet ist, weil Comet verlangt, dass Sie eine dauerhafte Verbindung zu jedem Browser-Client offen halten. Die Verwendung von mod_php bedeutet, dass für jeden Client, der überhaupt nicht skaliert, ein Apache-Kind in Vollzeit gebunden wird. Die Leute, die ich kenne, die Comet-Sachen machen, verwenden meistens Twisted Python, das dafür ausgelegt ist, Hunderte oder Tausende von gleichzeitigen Verbindungen zu verarbeiten.
Ist das wahr? Oder ist es etwas, das um konfiguriert werden kann?

Kothar
Ich stimme zu / erweitere das, was bereits gesagt wurde, und ich glaube nicht, dass FastCGI das Problem lösen wird.
Apache
Jede Anfrage an Apache verwendet einen Worker-Thread, bis die Anfrage abgeschlossen ist, was für COMET-Anfragen eine lange Zeit sein kann.
Dieser Artikel über Ajaxian erwähnt die Verwendung von COMET auf Apache, und dass es schwierig ist. Das Problem ist nicht spezifisch für PHP und gilt für alle Back-End-CGI-Module, die Sie möglicherweise auf Apache verwenden möchten.
Die vorgeschlagene Lösung war die Verwendung von ‘event’ MPM-Modul Dadurch ändert sich die Art und Weise, wie Anforderungen an Worker-Threads gesendet werden.
Dieses MPM versucht, das ‘Keep Alive Problem’ in HTTP zu beheben. Nachdem ein Client die erste Anforderung abgeschlossen hat, kann der Client die Verbindung offen halten und weitere Anforderungen über denselben Socket senden. Dies kann erheblichen Overhead beim Erstellen von TCP-Verbindungen einsparen. Apache lässt jedoch traditionell einen ganzen untergeordneten Prozess/Thread auf Daten vom Client warten, was seine eigenen Nachteile mit sich bringt. Um dieses Problem zu lösen, verwendet dieses MPM einen dedizierten Thread, um sowohl die Listening-Sockets als auch alle Sockets zu handhaben, die sich in einem Keep-Alive-Zustand befinden.
Leider funktioniert das auch nicht, weil es nur ‘snooze’ nach dem Eine Anfrage ist abgeschlossen und wartet auf eine neue Anfrage vom Client.
PHP
Betrachten wir nun die andere Seite des Problems, selbst wenn Sie das Problem lösen, indem Sie einen Thread pro Comet-Anfrage aufhalten, benötigen Sie immer noch einen PHP-Thread pro Anfrage – deshalb hilft FastCGI nicht.
Sie brauchen so etwas wie Fortsetzungen die es ermöglichen, die Comet-Anfragen wieder aufzunehmen, wenn das Ereignis, durch das sie ausgelöst wurden, beobachtet wird. AFAIK, das ist in PHP nicht möglich. Ich habe es nur in Java gesehen – siehe Apache Tomcat-Server.
Bearbeiten:
Dort ist ein Artikel hier über die Verwendung eines Load Balancers (HAProxy), damit Sie sowohl einen Apache-Server als auch einen Comet-fähigen Server (z. B. Jetty, Tomcat für Java) auf Port 80 desselben Servers ausführen können.

Jamie
Sie könnten Nginx und JavaScript verwenden, um ein Comet-basiertes Chat-System zu implementieren, das mit geringer Speicher- oder CPU-Auslastung sehr skalierbar ist.
Ich habe hier ein sehr einfaches Beispiel, das Ihnen den Einstieg erleichtern kann. Es behandelt das Kompilieren von Nginx mit dem NHPM-Modul und enthält Code für einfache Publisher/Subscriber-Rollen in jQuery, PHP und Bash.
http://blog.jamieisaacs.com/2010/08/27/comet-with-nginx-and-jquery/

Alfred
PHP
Ich fand das komisch wenig Screencasts einfachen Kometen erklären. Als Randbemerkung denke ich wirklich, dass dies Ihren Server bei jeder echten Last töten wird. Wenn Sie nur ein paar Benutzer haben, würde ich sagen, dass Sie sich einfach für diese Lösung entscheiden sollten. Diese Lösung ist wirklich einfach zu implementieren (Screencasts nehmen nur 5 Minuten Ihrer Zeit in Anspruch :)). Aber wie ich bereits sagte, denke ich nicht, dass es für viele gleichzeitige Benutzer gut ist (schätze, Sie sollten es bewerten;)), weil:
- Es verwendet Datei-I/O, was viel langsamer ist als nur das Abrufen von Daten aus dem Speicher. Wie zum Beispiel die Funktionen
filemtime()
,
- Zweitens, aber ich glaube nicht, dass PHP kein anständiges Thread-Modell hat. Dafür wurde PHP sowieso nicht ausgelegt Teilen Sie nichts Modell. Wie die Folien sagen, “Gemeinsam genutzte Daten werden auf die Datenspeicherebene verschoben”, wie zum Beispiel MySQL.
Alternativen
Ich denke wirklich, Sie sollten die Alternativen ausprobieren, wenn Sie Kometen-/Langabfragen durchführen möchten. Sie könnten viele Sprachen verwenden, wie zum Beispiel:
- Java/JVM: Steg Fortsetzungen.
- Python: Dustins Schwapp.
- Erlang: Volkssprache für Komet/etc.
- Lua, Ruby, C, Perl, um nur einige zu nennen.
Wenn Sie nur eine einfache Google-Suche durchführen, werden Ihnen viele Alternativen angezeigt, auch PHP (was meiner Meinung nach bei jeder großen Last Ihren Server töten wird).

vartec
mod_php ist nicht die einzige Möglichkeit, PHP zu verwenden. Sie können fastcgi verwenden. PHP muss mit kompiliert werden --enable-fastcgi
.
PHP als FastCGI: http://www.fastcgi.com/drupal/node/5?q=node/10

Gordon
Sie können es auch versuchen https://github.com/reactphp/react
React ist eine Low-Level-Bibliothek für die ereignisgesteuerte Programmierung in PHP. Im Kern befindet sich eine Ereignisschleife, auf der es Low-Level-Dienstprogramme bietet, wie z. B.: Streams-Abstraktion, asynchroner DNS-Resolver, Netzwerk-Client/Server, http-Client/Server, Interaktion mit Prozessen. Bibliotheken von Drittanbietern können diese Komponenten verwenden, um asynchrone Netzwerkclients/-server und mehr zu erstellen.
Die Ereignisschleife basiert auf dem Reaktormuster (daher der Name) und ist stark von Bibliotheken wie EventMachine (Ruby), Twisted (Python) und Node.js (V8) inspiriert.
Das einleitende Beispiel zeigt einen einfachen HTTP-Server, der auf Port 1337 lauscht:
<?php
$i = 0;
$app = function ($request, $response) use (&$i) {
$i++;
$text = "This is request number $i.\n";
$headers = array('Content-Type' => 'text/plain');
$response->writeHead(200, $headers);
$response->end($text);
};
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$http = new React\Http\Server($socket);
$http->on('request', $app);
$socket->listen(1337);
$loop->run();

Evan P.
Ich habe ein ähnliches Problem. Eine Option, die ich interessant finde, ist die Verwendung eines vorhandenen Comet-Servers wie cometd-java oder cometd-python als zentralen Nachrichten-Hub. Ihr PHP-Code ist dann nur ein Client für den Comet-Server – er kann Nachrichten von Kanälen posten oder lesen, genau wie andere Clients.
Hier ist ein interessantes Code-Snippet verlinkt: http://morglog.org/?p=22=1 das einen Teil dieser Methode implementiert (obwohl auch Teile des Debug-Codes herumgestreut sind).
Ich implementiere derzeit einen skalierbaren PHP Comet-Server mit Socket-Funktionen. Es heißt ‘phet’ ( [ph]p com[et] )
Projektseite: http://github.com/Tim-Smart/phet
Kostenlos kostenlos, um an der Entwicklung teilzunehmen. Ich habe es derzeit geschafft, den größten Teil der Serverlogik fertig zu stellen, muss nur noch die clientseitigen Dinge erledigen.
BEARBEITEN: Kürzlich hinzugefügte ‘Multi-Threading’-Funktionen mit der pcntl_fork
Methode 🙂
9887900cookie-checkKomet mit PHP verwenden?yes
Sie können PHP als fastcgi ausführen …
– Itay Moav-Malimovka
2. März 2009 um 17:46 Uhr
Verwenden Sie nodeJS als Server, um Client-Verbindungen aufrechtzuerhalten, Websockets in Javascript, um vom Browser aus eine Verbindung zum Server herzustellen. PHP in diesem Sinne kann ein privilegierter Client sein, der sich mit nodejs verbindet und einige Dienstdaten pusht, die irgendwie auf der Clientseite behandelt werden.
– Artjom Kurapov
20. März 2012 um 15:54 Uhr
@ArtjomKurapov Sie können PHP zu einem Webserver machen und so die Methode von Apache zur Bearbeitung von Anfragen umgehen – stellen Sie sich das wie einen echten PHP-Server vor, der sich um Comet-Anfragen kümmert nur.
– Christian
12. Juli 2012 um 8:21 Uhr
@Christian Wenn Sie seit 5.4 einen integrierten PHP-Webserver gemeint haben, ist dies nur für die Entwicklung und die Verwendung in der Produktion eine schlechte Idee
– Artjom Kurapov
13. Juli 2012 um 14:14 Uhr
@ArtjomKurapov Nein, ich meinte, einen echten PHP-Server zu schreiben, indem ich PHP-Sockets verwende, um Port 80 abzuhören und Eingaben auf unbestimmte Zeit zu blockieren – effektiv, wie Server funktionieren. Dies kann bereits in Aktion in Projekten wie gesehen werden phpwebsocket.
– Christian
13. Juli 2012 um 14:40 Uhr