82 votes

À l'aide de la comète avec le PHP?

Je pensais à mettre en œuvre le chat en temps réel à l'aide de PHP backend, mais j'ai couru à travers ce commentaire sur un site de discuter de la comète:

Ma compréhension est que PHP est un terrible la langue de la Comète, parce que La comète vous oblige à garder un connexion persistante à chaque navigateur client. À l'aide de ce mod_php faut attacher un enfant Apache à temps plein pour chaque client qui ne convient pas à tous. Les gens que j' le savoir faire de la Comète trucs sont pour la plupart à l'aide de 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ée?

61voto

Mike Houston Points 4320

Accepter/l'expansion de ce qui a déjà été dit, je ne pense pas que FastCGI permettra de résoudre le problème.

Apache

Chaque demande dans Apache utilise un thread jusqu'à ce que la demande se termine, ce qui peut être long pour la COMÈTE demandes.

Cet article sur Ajaxian mentionne l'utilisation de la COMÈTE sur Apache, et que c'est difficile. Le problème n'est pas spécifique à PHP, et s'applique à tout le back-end de module CGI vous souhaiterez peut-être utiliser sur un serveur Apache.

La solution proposée est d'utiliser les "événement" MPM module qui modifie la façon dont les demandes sont expédiés vers les threads de travail.

Ce MPM essaie de résoudre le problème le "keep alive" problème dans HTTP. Après un client a terminé la première demande, le client peut garder l' connexion ouverte, et envoyer d'autres les demandes en utilisant le même socket. Cette pouvez économiser de manière significative la surcharge due à la création de connexions TCP. Cependant, Apache traditionnellement conserve un ensemble de enfant de processus/thread en attente pour les données de la part du client, ce qui amène son propre les inconvénients. Pour résoudre ce problème, ce MPM utilise un thread dédié à l' gérer les sockets en Écoute, et tous les sockets dans un Keep Alive état.

Malheureusement, cela ne fonctionne pas non plus, car il ne 'snooze' après une demande est complète, en attente d'une nouvelle demande de la part du client.

PHP

Maintenant, compte tenu de l'autre côté du problème, même si vous résoudre la question de la détention de l'un thread par la comète de demande, vous aurez toujours besoin d'un PHP thread par la demande - c'est pourquoi FastCGI n'aidera pas.

Vous avez besoin de quelque chose comme des Prolongements qui permettent la comète demande à être repris lors de l'événement, ils sont déclenchés par est observée. Autant que je sache, ce n'est pas quelque chose qui est possible en PHP. J'ai seulement vu en Java - voir l'Apache Tomcat serveur.

Edit:

Il y a un article ici sur l'utilisation d'un répartiteur de charge (HAProxy) pour vous permettre d'exécuter à la fois un serveur apache et une comète serveur activée (par exemple, jetty, tomcat, Java) sur le port 80 de la même serveur.

14voto

Jamie Points 383

Vous pouvez utiliser Nginx et JavaScript pour mettre en œuvre une Comète basée sur un système de chat qui est très évolutif avec un peu de mémoire ou de l'utilisation de l'UC.

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

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

Un exemple de travail (chat simple) peut être trouvé ici:
http://cheetah.jamieisaacs.com/

10voto

Alfred Points 32190

PHP

J'ai trouvé ce drôle de petit screencasts expliquant simple comète. Comme une note de côté, je pense vraiment que ça va tuer votre serveur sur une véritable charge. Quand il suffit d'avoir un couple d'utilisateurs, je dirais d'aller juste pour cette solution. Cette solution est vraiment simple à mettre en œuvre(screencasts ne prend que 5 minutes de votre temps :)). Mais comme je te le disais précédemment, je ne pense pas que c'est bon pour beaucoup d'utilisateurs simultanés(Suppose que vous devriez référence ;)) parce que:

  1. Il utilise le fichier I/O qui est beaucoup plus lent que juste l'obtention des données de mémoire. Comme par exemple les fonctions filemtime(),
  2. La deuxième, mais je n'en pense pas moins PHP ne pas avoir une vie décente modèle de thread. PHP n'a pas été conçu pour cela de toute façon en raison de la part de rien. Comme les diapositives dit "de données Partagée est poussé vers le bas pour les données de magasin de la couche" comme par exemple MySQL.

Alternatives

Je pense vraiment que vous devriez essayer les solutions de rechange si vous voulez faire toute la comète/long des bureaux de vote. Vous pouvez utiliser de nombreuses langues, comme par exemple:

  • Java/JVM: la Jetée de continuations.
  • Python: Dustin de faire clapoter.
  • Erlang: la langue Populaire pour la comète/etc.
  • Lua, Ruby, C, Perl, pour n'en nommer que quelques-uns.

Juste en effectuant une simple recherche google, va vous montrer beaucoup de solutions de rechange aussi PHP(que je pense sur tout le gros de la charge va tuer votre serveur).

7voto

vartec Points 53382

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

PHP en FastCGI: http://www.fastcgi.com/drupal/node/5?q=node/10

6voto

Gordon Points 156415

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

Réagir est une bibliothèque bas niveau pour la programmation événementielle en PHP. En son centre se trouve une boucle d'événements, au sommet de laquelle il fournit à faible niveau de services publics, tels que: les Flux d'abstraction, async dns resolver, réseau client/serveur http, client/serveur, l'interaction avec les processus. Les bibliothèques de tiers peuvent utiliser ces composants pour créer réseau asynchrone clients/serveurs et plus.

La boucle d'événement est basé sur le modèle de réacteur (d'où le nom) et fortement inspiré par les bibliothèques comme EventMachine (Ruby), Tordue (en Python) et Node.js (V8).

L'introduction montre l'exemple d'un simple serveur HTTP à l'écoute 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();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X