Frage
Ich dachte an Echtzeit-Chat-Implementierung eines PHP-Backend, aber ich über diesen Kommentar lief auf einer Website zum Thema Kometen:
Mein Verständnis ist, dass PHP a schreckliche Sprache für Comet, weil Comet erfordert, dass Sie ein halten persistente Verbindung offen zu jedem Browser-Client. Mit Mod_php dieser bedeutet ein Apache-Kind binden Vollzeit für jeden Kunden der gar nicht maßstäblich. Die Leute, die ich wissen Comet Sachen zu tun sind meist Verwendung Verdreht Python, die ausgelegt ist, zu behandeln Hunderte oder Tausende von gleichzeitige Verbindungen.
Ist das wahr? Oder ist es etwas, das um konfiguriert werden kann?
Lösung
Die Zustimmung / -erweiterung, was bereits gesagt wurde, ich glaube nicht, FastCGI wird das Problem lösen.
Apache
Jede Anforderung in Apache wird einen Worker-Thread verwenden, bis die Anforderung abgeschlossen ist, das eine lange Zeit für die COMET-Anfragen werden kann.
Dieser Artikel auf Ajaxian erwähnt COMET auf Apache verwendet wird, und dass es ist schwierig. Das Problem ist nicht spezifisch für PHP, und gilt für alle Back-End-CGI-Modul Sie können auf Apache verwenden.
Die vorgeschlagene Lösung die ‚Ereignis‘ MPM-Modul zu verwenden war die ändert sich die Art und Weise Anfragen Menge zu worker-Threads.
Dieses MPM versucht zu beheben die 'Keep-Alive-Problem' in HTTP. Nachdem ein Client vervollständigt die erste Wunsch kann der Kunde die halten Verbindung offen, und sendet weiter Anfragen der gleichen Buchse verwendet wird. Diese kann signifigant Aufwand sparen in Erstellen von TCP-Verbindungen. Jedoch, Apache hält traditionell eine ganze Kind Prozess / Thread wartet auf Daten vom Client, die ihre eigenen bringt Nachteile. Um dieses Problem zu lösen, Dieses MPM verwendet einen speziellen Thread Griff sowohl die Listening-Buchsen und alle Steckdosen, die in einem Haltungsart sind lebendiges Zustand.
Leider, das funktioniert auch nicht, denn es wird nur ‚Snooze‘ nach eine Anfrage abgeschlossen ist, vom Client für eine neue Anforderung zu warten.
PHP
Nun, die andere Seite des Problems unter Berücksichtigung, auch wenn Sie das Problem beheben mit hält einen Thread pro Kometen Anfrage, werden Sie noch brauchen einen PHP Thread pro Anfrage - deshalb FastCGI wird nicht helfen
Sie brauchen so etwas wie Fortsetzungen die es erlauben, die Kometen-Anforderungen wieder aufgenommen werden, wenn das Ereignis sie sind ausgelöst durch beobachtet. AFAIK, das ist nicht etwas, das in PHP möglich ist. Ich habe es nur in Java zu sehen - siehe den Apache Tomcat-Server .
Edit:
Es gibt einen Artikel hier über einen Load Balancer mit ( HAProxy ), damit Sie sowohl einen apache-Server und einen Kometen-fähigen Server (zB laufen Anlegesteg, tomcat für Java) auf Port 80 von dem gleichen Server.
Andere Tipps
Sie könnten Nginx und JavaScript verwenden, um einen Comet basierte Chat-System zu implementieren, die mit wenig Speicher oder CPU-Auslastung sehr skalierbar ist.
Ich habe ein sehr einfaches Beispiel hier, die bekommen Sie begonnen haben. Es umfasst Nginx mit dem NHPM Modul kompiliert und enthält Code für eine einfache Publisher / Subscriber-Rollen in jQuery, PHP und Bash.
http: //blog.jamieisaacs. com / 2010/08/27 / Komet-with-nginx-and-jquery /
PHP
Ich fand diesen lustigen kleinen Screencasts erklären einfache Kometen. Als Randbemerkung denke ich wirklich das Ihren Server auf einer wirklichen Last töten wird. Wenn nur ein paar Benutzer mit, würde ich sagen, nur für diese Lösung zu gehen. Diese Lösung ist sehr einfach zu implementieren (Screencasts nur dauert 5 Minuten Ihrer Zeit :)). Aber wie ich schon sagen, vorher habe ich nicht denke, dass es für viele gleichzeitige Benutzer gut ist (Raten Sie sollten Benchmark it;)), weil:
- Es verwendet Datei-I / O, die dann viel langsamer ist nur Daten aus dem Speicher zu bekommen. Wie zum Beispiel der Funktionen
filemtime()
, - Zweitens, aber ich glaube nicht zuletzt PHP ein kein ordentliches Thread-Modell hat. PHP wurde nicht wegen der nichts Modell teilen. Wie die Dias sagt wie zum Beispiel MySQL „Gemeinsame Daten werden an die Datenspeicher-Schicht nach unten gedrückt“.
Alternativen
Ich glaube wirklich, sollten Sie die Alternativen versuchen, wenn Sie irgendeine Komet / Lang-Abfrage tun wollen. Sie könnten viele Sprachen wie zum Beispiel verwenden:
- Java / JVM. Jetty Fortsetzungen
- Python: Dustin Schwappen .
- Erlang: Beliebte Sprache für Kometen / etc .
- Lua, Ruby, C, Perl um nur einige zu nennen.
Nur eine einfache Google-Suche durchgeführt wird, zeigt Ihnen eine Menge Alternativen auch PHP (die ich auf jede große Last denken wird Ihr Server töten).
Mod_php ist nicht der einzige Weg, um PHP zu verwenden. Sie können fastcgi verwenden. PHP muss mit --enable-fastcgi
kompiliert werden.
PHP als FastCGI: http://www.fastcgi.com/ drupal / Knoten / 5? q = node / 10
Sie können auch versuchen, https://github.com/reactphp/react
Reagierenist eine Low-Level-Bibliothek für ereignisgesteuerte Programmierung in PHP. Im Kern ist eine Ereignisschleife, oben auf das sie Low-Level-Dienstprogramme wie bieten: Strom Abstraktion, async dns Resolver, Netzwerk-Client / Server, HTTP-Client / Server-Interaktion mit Prozessen. Bibliotheken von Drittanbietern diese Komponenten verwenden können Asynchron-Netzwerk-Clients / Server und vieles mehr.
erstellenDie Ereignisschleife auf dem Reactor basiert (daher der Name) und stark inspiriert von Bibliotheken wie eventmachine (Rubin), Verdreht (Python) und Node.js (V8).
Das einführende Beispiel zeigt ein einfacher HTTP-Server auf Port lauscht 1337:
<?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();
Ich habe ein ähnliches Problem. Eine Option Ich finde interessant ist, einen vorhandenen Comet-Server zu verwenden, wie cometd-java oder cometd-Python, als Kern Nachricht Hub. Ihr PHP-Code ist dann nur ein Client mit dem Comet-Server -. Es Nachrichten von Kanälen veröffentlichen oder lesen kann, wie andere Kunden
Es ist ein interessanter Code-Schnipsel hier verknüpft: http://morglog.org/?p=22 = 1 , die Teil dieses Verfahren implementiert (obwohl es Bits von debug Code gespreizt herum, auch).
Ich bin Strom einen skalierbares PHP Comet-Server mit Socket-Funktionen zu implementieren. Es heißt 'Phet' genannt ([ph] p com [et])
Projekt Seite: http://github.com/Tim-Smart/phet
Free frei in auf Entwicklung zu verbinden. Ich habe zur Zeit bekommen die meisten der Server-Logik durchgeführt, müssen nur fertig machen die Client-Seite Sachen verwaltet.
EDIT: Zuletzt hinzugefügt 'Multi-Threading' Fähigkeiten der pcntl_fork
Methode:)
Sie haben eine harte Zeit haben Kometen in PHP Implementierung, nur weil es inhärent Single-Threaded-ness ist.
Schauen Sie sich websync On-Demand - der Service können Sie PHP über serverseitige Publishing integrieren, Abladen der schweren gleichzeitige Verbindung Sachen, und lassen Sie in kürzester Zeit eine Echtzeit-Chat-Anwendung erstellen.
Ein neues Modul kam gerade heraus für den nginx Web-Server, der Comet mit einem beliebigen Sprache erlauben wird, einschließlich PHP.
http: // www. igvita.com/2009/10/21/nginx-comet-low-latency-server-push/
In Kürze erhalten Sie haben Ihren eigenen Server in PHP erstellen. Apache / mod_php oder sogar fastcgi wird überhaupt nicht maßstäblich. Ein paar Jahre alt, aber können Sie den Einstieg:
PHP-Comet-Server: http://sourceforge.net/projects/comet/
Ich denke, das Problem ist, dass viele Apache-Fäden, läuft die ganze Zeit ein Problem ist. Das bestehende mit jeder Sprache, wenn es über Apache in der gleichen Weise wie PHP (in der Regel) arbeitet der Fall ist.