Używanie comet z PHP?

Myślałem o zaimplementowaniu czatu w czasie rzeczywistym za pomocą backendu PHP, ale natknąłem się na ten komentarz na stronie omawiającej kometę:

Rozumiem, że PHP jest okropny język dla komety, bo Comet wymaga, aby zachować stałe połączenie otwarte dla każdego klient przeglądarki. Using mod_php this oznacza związanie dziecka Apaczów Pełny etat dla każdego klienta, który w ogóle się nie skaluje. Ludzie I wiem, że robienie komet to głównie korzystanie z Twisted Python który jest przeznaczony do obsługi setek lub tysięcy jednoczesne połączenia.

Czy to prawda? A może jest to coś, co można skonfigurować wokół?

 82
Author: ryeguy, 2009-03-02

11 answers

Zgadzając się/rozszerzając to, co już zostało powiedziane, nie sądzę, że FastCGI rozwiąże problem.

Apache

Każde żądanie do Apache będzie używać jednego wątku roboczego, dopóki żądanie się nie zakończy, co może być długim czasem dla zapytań COMET.

Ten artykuł na Ajaxian wspomina o używaniu COMET na Apache, i że jest to trudne. Problem nie jest specyficzny dla PHP i dotyczy dowolnego modułu CGI, którego możesz chcieć użyć na Apache.

Sugerowane rozwiązanie było użycie modułu MPM 'event', który zmienia sposób wysyłania żądań do wątków roboczych.

Ten MPM próbuje naprawić problem "keep alive" w HTTP. Po zakończeniu przez Klienta pierwszego żądanie, klient może zachować połączenie otwarte, i wysłać dalej żądania przy użyciu tego samego gniazda. To może zaoszczędzić znaczące koszty w tworzenie połączeń TCP. Jednakże, Apache tradycyjnie utrzymuje cały proces potomny / wątek oczekujący na dane z klienta, który przynosi własne wady. Aby rozwiązać ten problem, ten MPM wykorzystuje dedykowany wątek do obsługiwać zarówno gniazda nasłuchowe, jak i wszystkie gniazda, które są w Keep Alive stan.

Niestety, to również nie działa, ponieważ tylko "uśpi" Po zakończeniu żądania, czekając na nowe żądanie od klienta.

PHP

Teraz, biorąc pod uwagę drugą stronę problemu, nawet jeśli rozwiążesz problem trzymając jeden thread per request, nadal będziesz potrzebował jednego wątku PHP per request - dlatego FastCGI nie pomoże.

Potrzebujesz czegoś w rodzaju kontynuacji , które pozwolą na wznowienie żądań komety, gdy nastąpi obserwacja zdarzenia, przez które są wywołane. AFAIK, to nie jest coś co jest możliwe w PHP. Widziałem go tylko w Javie-zobacz serwer Apache Tomcat .

Edit:

Jest Artykuł o używaniu load balancer (HAProxy ), aby umożliwić uruchamianie zarówno serwera apache, jak i serwera obsługującego comet (np. jetty, tomcat for Java) na porcie 80 tego samego serwera.

 61
Author: Mike Houston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-27 16:33:09

Możesz użyć Nginx i JavaScript, aby zaimplementować system czatu oparty na komecie, który jest bardzo skalowalny przy niewielkim wykorzystaniu pamięci lub procesora.

Mam tutaj bardzo prosty przykład, który może zacząć. Obejmuje kompilację Nginx z modułem nhpm i zawiera kod dla prostych ról wydawców/subskrybentów w jQuery, PHP i Bash.

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

 14
Author: Jamie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 20:50:34

PHP

Znalazłem ten zabawny mały screencasts wyjaśniający prostą kometę. Na marginesie naprawdę myślę, że to zabije Twój serwer przy każdym prawdziwym obciążeniu. Kiedy tylko kilku użytkowników, powiedziałbym, aby po prostu przejść do tego rozwiązania. To rozwiązanie jest naprawdę proste do wdrożenia (screencasty zajmują tylko 5 minut twojego czasu :)). Ale jak już wcześniej mówiłem, nie sądzę, że jest to dobre dla wielu równoczesnych użytkowników(chyba powinieneś go porównywać ;)) ponieważ:

  1. używa plików We / Wy, które są znacznie wolniejsze niż pobieranie danych z pamięci. Jak na przykład funkcje filemtime(),
  2. Po drugie, ale myślę, że przynajmniej PHP nie ma przyzwoitego modelu wątku. PHP i tak nie zostało do tego zaprojektowane ze względu na model share nothing . Jak na slajdach jest napisane "udostępniane dane są wypychane w dół do warstwy przechowywania danych", jak na przykład MySQL.

Alternatywy

Naprawdę uważam, że powinieneś wypróbować alternatywy, jeśli chcesz zrobić any comet/long ankiet. Możesz używać wielu języków, takich jak na przykład:
  • Java / JVM: Jetty kontynuacje.
  • Python: Dustin ' s slosh .
  • Erlang: popularny język dla komet / etc.
  • Lua, Ruby, C, Perl, żeby wymienić tylko kilka.

Po prostu wykonując proste wyszukiwanie w google, pokaże Ci wiele alternatyw również PHP (które myślę, że przy każdym dużym obciążeniu zabije Twój serwer).

 10
Author: Alfred,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:02

Mod_php nie jest jedynym sposobem użycia PHP. Możesz użyć fastcgi. PHP musi być skompilowane z --enable-fastcgi.

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

 7
Author: vartec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 17:52:34

Możesz również spróbować https://github.com/reactphp/react

React jest niskopoziomową biblioteką do programowania sterowanego zdarzeniami w PHP. Jego rdzeniem jest pętla zdarzeń, na której dostarcza niskopoziomowe narzędzia, takie jak: streams abstraction, async DNS resolver, network client/server, http client/server, interakcja z procesami. Biblioteki innych firm mogą używać tych komponentów do tworzenia klientów/serwerów sieci asynchronicznej i nie tylko.

Pętla zdarzeń opiera się na Reactor pattern (stąd nazwa) i silnie inspirowany bibliotekami takimi jak EventMachine (Ruby), Twisted (Python) i Node.js (V8).

Przykład wprowadzający pokazuje prosty serwer HTTP nasłuchujący na porcie 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
Author: Gordon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-21 09:54:41

Mam podobny problem. Jedną z opcji, którą uważam za interesującą, jest użycie istniejącego serwera Comet, takiego jak cometd-java lub cometd-python, jako głównego centrum wiadomości. Twój kod PHP jest wtedy tylko klientem serwera Comet - może wysyłać lub odczytywać wiadomości z kanałów, tak jak inni klienci.

Tutaj jest ciekawy fragment kodu: http://morglog.org/?p=22=1 , która implementuje część tej metody (chociaż istnieją również bity kodu debugującego).

 4
Author: Evan P.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-24 21:05:13

Obecnie implementuję skalowalny serwer PHP Comet przy użyciu funkcji socket. Nazywa się "phet" ([ph]p com [et])

Strona projektu: http://github.com/Tim-Smart/phet

Free free to join in on development. Obecnie udało mi się zrobić większość logiki serwera, wystarczy dokończyć rzeczy po stronie klienta.

EDIT: Ostatnio dodane możliwości 'wielowątkowości' przy użyciu metody pcntl_fork:)

 3
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-23 14:24:28

Będziesz miał problem z implementacją comet w PHP, tylko dlatego, że jest to nieodłączna jednowątkowość.

Sprawdź Websync On-Demand - usługa pozwala zintegrować PHP poprzez publikowanie po stronie serwera, odciążając ciężkie współbieżne połączenia i pozwoli Ci stworzyć aplikację do czatu w czasie rzeczywistym w mgnieniu oka.

 3
Author: jvenema,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-04 15:23:03

Właśnie pojawił się nowy moduł dla serwera WWW nginx, który umożliwi obsługę dowolnego języka, w tym PHP.

Http://www.igvita.com/2009/10/21/nginx-comet-low-latency-server-push/

 1
Author: ceejayoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-23 14:30:16

Będziesz musiał utworzyć własny serwer w PHP. Używanie Apache / mod_php lub nawet fastcgi w ogóle nie będzie skalowane. Kilka lat, ale można zacząć:

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

 1
Author: sroussey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-23 19:51:41

Myślę, że jest to bardziej problem, że posiadanie wielu wątków apache działających przez cały czas jest problemem. Będzie to możliwe w każdym języku, jeśli działa poprzez apache w taki sam sposób jak PHP (zazwyczaj).

 0
Author: benlumley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 17:48:11