BlogKontaktTagcloud

AJAX-Chat in PHP mit UNIX IPC

Das AJAX-Chats und ander Multi-User AJAX-Anwendungen nicht nur Clientseitig spezielle Technologien benötigen ist wohl den meisten klar. In Java bittet dazu Web-Continuations eine gute Hilfe um die Server-Last tief zu halten. Mit der Share-Nothing-Architecture von PHP ist eine solche Technologie jedoch nicht möglich.

Was tun wenn man nicht lange pollen will und so unnötig Resourcen auf dem Server blockiert. Meine Überlegung ist die IPC (interprocess communication) Funktionen von Unix zu verwenden um die Nachrichten auf dem Server auszutauschen. PHP unterstützt IPC bereits out-of-the-box.

Jeder Client erhält wenn er sich anmeldet eine eigene Message-Queue in die die für ihn bestimmte Nachrichten liegen. Die Nummer für die Queue muss eindeutig sein, die Nummer wird von mir aus einem Shared Memory Bereich gelesen (könnte aber ebenso gut mit einem File oder DB geschehen).

Für das Verteilen der Nachrichten an alle Clients wird ein kleiner Server (PHP-Script) gestartet, der ebenfalls eine Message-Queue hat. Alle von Clients geschrieben Nachrichten werden über die Queue an den Server gesendet und dieser Verteilt diese Nachricht dann an die Queues der Clients.

Da msg_receive über keinen Timeout verfügt, kann die Methode zum Abfragen der Queue nicht blockierend verwendet werden. Mit einem kurzen Sleep wird die Methode nun einfach maximal 30 mal aufgerufen. Sobald Daten in der Queue liegen werden diese an den Client geliefert und dieser fragt anschliessend erneut an. Werden keine Daten in die Queue gelegt wird dem Client ein 204 zurückgeliefert, worauf dieser ebenfalls erneut pollt.

Schematisch sieht das dann etwa so aus.



Das ganze ist ein Design-Studie. Wenn man ein solches System produktiv einsetzen möchte müsste man mindestens folgendes verbessern:
  • Mal überlegen ob das überhaupt funktioniert ;-)
  • Code für produktive Systeme sollte nicht so aussehen wie meiner hier!
  • Benutzerverwaltung
  • Zuordnen der Message Queues Nummer mit einem Semaphor schützen
  • Gesendete Nachricht beim Sender direkt mit JavaScript anzeigen (Verbesserte Usability, Response-Time)
  • Garbage Collecting von nicht mehr verwendeten Message Queues
  • Sicherheit der Message Queues mit korrekter Berechtigung
  • Wenn mehrere Messages in der Queue liegen diese zusammen übertragen.
  • Wer dann wirklich genug Zeit hat sollte die PHP (und Unix-Funktion) msg_receive mit einem Timeout ausstatten.
Denn Code kann man hier herunterladen. Wichtig ist das der Server (ipc-server.php) zuerst gestartet wird.

Zuletzt bleibt hier noch einen Dank an Georg für den Support bei meinen CSS Fragen.
Ähnliche Beiträge:
Parallel Request mit AJAX und PHP
PHP Quine
What's php like?
All new webtuesday
Zend Framwork 1.5 is out
Comments (5)  Permalink

comments

Robert @ 09.06.2007 14:38 CEST
Hallo,
nett geschriebener Artikel.

Könntest du bitte den Link des Pakets fixen, da ich mich mit Interprozesskommunikation unter PHP beschäftigen will und deine Quellen gern als Beispiel hätte.

Vielen Dank,
Gruß Robert
leo @ 10.06.2007 17:43 CEST
Sorry, da hatte ich wohl ein wenig Probleme mit meiner Blogsoftware. Nun sollte es gehen.
leo @ 17.06.2007 10:42 CEST
Note to myself: NOTIFY/LISTEN in PgSQL wäre auch eine Implementationsmöglichkeit. Siehe Wez.
Sebastian @ 13.03.2008 20:31 CEST
Hey, ich habe das mal zum Anlass genommen, so ein System zu programmieren...

Ich bin dabei aber auf ein Problem gestoßen: Denn Standartmäßig sind nur 16-20 Messag Queues pro Server erlaubt. D.h. nur 20 User -.-

Gruß
Sebastian
leo @ 11.05.2008 11:28 CEST
Ich habe leider nie herausgefunden wieviel queues das möglich sind. Das ganze war ziemlich lustig zum implementieren, aber heute würde ich wohl einen Jabberserver als Backend nehmen.

add a comment

The Trackback URL to this comment is:
http://leo.freeflux.net/blog/plugin=trackback(2215).xml

This blog is gravatar enabled.
Your email adress will never be published.
Comment spam will be deleted!

Name*
E-Mail
For Spammers Only
URL
Kommentar*
E-Mail Benachrichtigung bei neuen Kommentaren zu diesem Eintrag
Speichere meine Daten (braucht Cookies)