web-dev-qa-db-fra.com

Vous utilisez comète avec PHP?

Je pensais à implémenter le chat en temps réel en utilisant un backend PHP, mais j'ai rencontré ce commentaire sur un site discutant de la comète:

Ma compréhension est que PHP est un langage terrible pour Comet, car Comet vous oblige à garder une connexion persistante ouverte à chaque client de navigateur. En utilisant mod_php, cela signifie attacher un enfant Apache à temps plein pour chaque Le client que je connais qui fait des trucs Comet utilise principalement Twisted Python qui est conçu pour gérer des centaines ou des milliers de connexions simultanées.

Est-ce vrai? Ou est-ce quelque chose qui peut être configuré autour?

82
ryeguy

D'accord/élargir ce qui a déjà été dit, je ne pense pas que FastCGI résoudra le problème.

Apache

Chaque demande dans Apache utilisera un thread de travail jusqu'à la fin de la demande, ce qui peut être long pour les demandes COMET.

Cet article sur Ajaxian mentionne l'utilisation de COMET sur Apache, et c'est difficile. Le problème n'est pas spécifique à PHP et s'applique à tout module CGI back-end que vous souhaitez utiliser sur Apache.

La solution suggérée était d'utiliser le module MPM 'event' qui change la façon dont les requêtes sont envoyées aux threads de travail.

Ce MPM essaie de résoudre le "problème de persistance" dans HTTP. Une fois qu'un client a terminé la première demande, le client peut garder la connexion ouverte et envoyer d'autres demandes à l'aide du même socket. Cela peut réduire les frais généraux importants lors de la création de connexions TCP. Cependant, Apache conserve traditionnellement un processus/thread enfant entier en attente de données du client, ce qui présente ses propres inconvénients. Pour résoudre ce problème, ce MPM utilise un thread dédié pour gérer à la fois les sockets d'écoute et toutes les sockets qui sont dans un état Keep Alive.

Malheureusement, cela ne fonctionne pas non plus, car cela ne fera que "répéter" après une demande est terminée, en attente d'une nouvelle demande du client.

PHP

Maintenant, compte tenu de l'autre côté du problème, même si vous résolvez le problème en bloquant un thread par demande de comète, vous aurez toujours besoin d'un PHP thread par demande - c'est pourquoi FastCGI a gagné ' t aider.

Vous avez besoin de quelque chose comme Continuations qui permet de reprendre les requêtes de comètes lorsque l'événement auquel elles sont déclenchées est observé. AFAIK, ce n'est pas quelque chose qui est possible en PHP. Je ne l'ai vu qu'en Java - voir Apache serveur Tomcat .

Modifier:

Il y a un article ici sur l'utilisation d'un équilibreur de charge ( HAProxy ) pour vous permettre d'exécuter à la fois un serveur Apache et un serveur compatible comète (par exemple jetty, Tomcat pour Java) sur port 80 du même serveur.

61
Mike Houston

Vous pouvez utiliser Nginx et JavaScript pour implémenter un système de chat basé sur Comet qui est très évolutif avec peu de mémoire ou d'utilisation du processeur.

J'ai ici un exemple très simple qui peut vous aider à démarrer. Il couvre la compilation de Nginx avec le module NHPM et inclut du code pour les rôles simples d'éditeur/abonné dans jQuery, PHP et Bash.

http://blog.jamieisaacs.com/2010/08/27/comet-with-nginx-and-jquery/

14
Jamie

PHP

J'ai trouvé ce petit drôle screencasts expliquant la comète simple. En remarque, je pense vraiment que cela va tuer votre serveur sur n'importe quelle charge réelle. Lorsque je n'ai que quelques utilisateurs, je dirais de choisir cette solution. Cette solution est vraiment simple à mettre en œuvre (les screencasts ne prennent que 5 minutes de votre temps :)). Mais comme je le disais précédemment, je ne pense pas que ce soit bon pour beaucoup d'utilisateurs simultanés (je suppose que vous devriez le comparer;)) parce que:

  1. Il utilise les E/S de fichiers, ce qui est beaucoup plus lent que d'obtenir simplement des données de la mémoire. Comme par exemple les fonctions filemtime(),
  2. Deuxièmement, mais je ne pense pas le moins PHP n'a pas de modèle de thread décent. PHP n'a pas été conçu pour cela de toute façon à cause de modèle de partage de rien . Comme le montrent les diapositives, "les données partagées sont poussées vers la couche de stockage de données" comme par exemple MySQL.

Alternatives

Je pense vraiment que vous devriez essayer les alternatives si vous voulez faire des comètes/longs sondages. Vous pouvez utiliser de nombreuses langues comme par exemple:

  • Java/JVM: Jetty suites .
  • Python: Dustin slosh .
  • Erlang: langue populaire pour la comète/etc.
  • Lua, Ruby, C, Perl pour n'en nommer que quelques-uns.

Le simple fait d'effectuer une simple recherche sur Google vous montrera de nombreuses alternatives également PHP (qui, je pense, sur n'importe quelle grosse charge tuera votre serveur).

10
Alfred

mod_php n'est pas la seule façon d'utiliser PHP. Vous pouvez utiliser fastcgi. PHP doit être compilé avec --enable-fastcgi.

PHP comme FastCGI: http://www.fastcgi.com/drupal/node/5?q=node/1

7
vartec

Vous pouvez également essayer https://github.com/reactphp/react

React est une bibliothèque de bas niveau pour la programmation événementielle en PHP. Au cœur se trouve une boucle d'événements, au-dessus de laquelle il fournit des utilitaires de bas niveau, tels que: abstraction de flux, résolveur async dns, client/serveur réseau, client/serveur http, interaction avec les processus. Les bibliothèques tierces peuvent utiliser ces composants pour créer des clients/serveurs réseau asynchrones et plus encore.

La boucle d'événement est basée sur le modèle de réacteur (d'où le nom) et fortement inspirée de bibliothèques telles que EventMachine (Ruby), Twisted (Python) et Node.js (V8).

L'exemple d'introduction montre un serveur HTTP simple écoutant sur le port 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();
6
Gordon

J'ai un problème similaire. Une option que je trouve intéressante consiste à utiliser un serveur Comet existant, comme cometd-Java ou cometd-python, comme centre de messages principal. Votre code PHP n'est alors qu'un client du serveur Comet - il peut publier ou lire des messages à partir de canaux, tout comme les autres clients.

Il y a un extrait de code intéressant lié ici: http://morglog.org/?p=22=1 qui implémente une partie de cette méthode (bien qu'il y ait aussi des bouts de code de débogage).

4
Evan P.

Je suis en train d'implémenter un serveur de comète PHP Comet utilisant des fonctions de socket. Il s'appelle 'phet' ([ph] p com [et])

Page du projet: http://github.com/Tim-Smart/phet

Gratuit et gratuit pour participer au développement. J'ai actuellement réussi à faire la plupart de la logique du serveur, juste besoin de terminer les trucs côté client.

EDIT: récemment ajouté des fonctionnalités de "multi-threading" en utilisant le pcntl_fork méthode :)

3
Tim

Vous aurez du mal à implémenter la comète en PHP, simplement en raison de son caractère unique à thread unique.

Découvrez Websync On-Demand - le service vous permet d'intégrer PHP via la publication côté serveur, en déchargeant le lourd matériel de connexion simultanée, et vous permettra de créer un réel- application de chat en un rien de temps.

3
jvenema

Un nouveau module vient de sortir pour le serveur Web nginx qui permettra à Comet avec n'importe quel langage, y compris PHP.

http://www.igvita.com/2009/10/21/nginx-comet-low-latency-server-Push/

1
ceejayoz

Vous devrez créer votre propre serveur en PHP. L'utilisation d'Apache/mod_php ou même de fastcgi ne sera pas du tout mise à l'échelle. A quelques années, mais peut vous aider à démarrer:

PHP-Comet-Server: http://sourceforge.net/projects/comet/

1
sroussey

Je pense que c'est plus un problème que d'avoir beaucoup de threads Apache en cours d'exécution est un problème. Cela existera avec n'importe quel langage s'il fonctionne via Apache de la même manière que PHP (habituellement).

0
benlumley