Использование кометы с PHP? - PullRequest
82 голосов
/ 02 марта 2009

Я думал о реализации чата в реальном времени с помощью бэкэнда PHP, но наткнулся на этот комментарий на сайте, обсуждающем комету:

Я понимаю, что PHP - это ужасный язык для кометы, потому что Комета требует от вас держать постоянное соединение открыто для каждого браузерный клиент. Используя mod_php это означает связать ребенка Apache полный рабочий день для каждого клиента, который не масштабируется вообще. Люди, которых я знаю, что делать вещи кометы в основном используя Twisted Python, который разработан обрабатывать сотни или тысячи одновременные подключения.

Это правда? Или это то, что можно настроить вокруг?

Ответы [ 11 ]

61 голосов
/ 23 ноября 2009

Соглашаясь / расширяя сказанное, я не думаю, что FastCGI решит проблему.

Apache

Каждый запрос в Apache будет использовать один рабочий поток до его завершения, что может занять длительное время для запросов COMET.

В этой статье на Ajaxian упоминается использование COMET на Apache, и это сложно. Эта проблема не является специфичной для PHP и относится к любому внутреннему CGI-модулю, который вы можете использовать в Apache.

Предлагаемое решение заключалось в использовании модуля MPM 'event' , который изменяет способ отправки запросов в рабочие потоки.

Этот MPM пытается исправить «проблема поддержания жизни» в HTTP. После того, как клиент завершает первый запрос, клиент может сохранить Соединение открой и отправь дальше запросы с использованием одного и того же сокета. это может сохранить значительные накладные расходы в создание TCP-соединений. Тем не мение, Апач традиционно держит целый дочерний процесс / поток, ожидающий данных от клиента, который приносит свой недостатки. Для решения этой проблемы, этот MPM использует выделенный поток для обрабатывать как сокеты прослушивания, и все розетки, которые находятся в Keep Alive состояние.

К сожалению, это тоже не сработает, потому что он будет только 'snooze' после того, как запрос завершен, ожидая новый запрос от клиента.

PHP

Теперь, учитывая другую сторону проблемы, даже если вы решите проблему с удержанием одного потока на запрос кометы, вам все равно потребуется один поток PHP на запрос - вот почему FastCGI не поможет.

Вам нужно что-то вроде Continuations , которое позволяет возобновлять запросы кометы, когда наблюдается событие, вызванное ими. AFAIK, это не то, что возможно в PHP. Я видел это только на Java - см. Сервер Apache Tomcat .

Edit:

Здесь есть статья об использовании балансировщика нагрузки ( HAProxy ), чтобы позволить вам запускать как сервер apache, так и сервер с поддержкой комет (например, jetty, tomcat для Java) на порт 80 того же сервера.

14 голосов
/ 28 августа 2010

Вы можете использовать Nginx и JavaScript для реализации системы чата на основе Comet, которая очень масштабируема с небольшим использованием памяти или ЦП.

У меня есть очень простой пример, который поможет вам начать. Он охватывает компиляцию Nginx с помощью модуля NHPM и включает код для простых ролей издателя / подписчика в jQuery, PHP и Bash.

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

10 голосов
/ 25 августа 2009

PHP

Я нашел эту забавную заставку , объясняющую простую комету. Как примечание стороны, я действительно думаю, что это убьет ваш сервер при любой реальной нагрузке. Когда у меня просто пара пользователей, я бы сказал, что нужно просто пойти на это решение. Это решение очень просто реализовать (скринкасты занимают всего 5 минут вашего времени :)). Но, как я уже говорил ранее, я не думаю, что это хорошо для многих одновременно работающих пользователей (думаю, вы должны сравнить его;)), потому что:

  1. Он использует файловый ввод / вывод, который намного медленнее, чем просто получение данных из памяти. Как например функции filemtime(),
  2. Во-вторых, но я не думаю, что, по крайней мере, PHP не имеет достойной модели потоков. В любом случае, PHP не был разработан для этого из-за модели без общего доступа . Как показано на слайдах: «Общие данные передаются на уровень хранилища данных», как, например, MySQL.

Альтернативы

Я действительно думаю, что вы должны попробовать альтернативы, если вы хотите провести какой-либо кометный / длинный опрос. Вы можете использовать много языков, например:

  • Java / JVM: Jetty продолжения .
  • Питон: Дастин слош .
  • Erlang: популярный язык для кометы и т. Д.
  • Lua, Ruby, C, Perl, лишь некоторые из них.

Простое выполнение поиска в Google покажет вам множество альтернатив, в том числе PHP (который, я думаю, при любой большой нагрузке убьет ваш сервер).

7 голосов
/ 02 марта 2009

mod_php - не единственный способ использовать PHP. Вы можете использовать fastcgi. PHP должен быть скомпилирован с --enable-fastcgi.

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

6 голосов
/ 21 января 2013

Вы также можете попробовать https://github.com/reactphp/react

React - это низкоуровневая библиотека для событийно-управляемого программирования в PHP. В его основе лежит цикл обработки событий, поверх которого он предоставляет утилиты низкого уровня, такие как: абстракция потоков, асинхронный преобразователь DNS, сетевой клиент / сервер, http клиент / сервер, взаимодействие с процессами. Сторонние библиотеки могут использовать эти компоненты для создания асинхронных сетевых клиентов / серверов и т. Д.

Цикл событий основан на шаблоне реактора (отсюда и название) и навеян такими библиотеками, как EventMachine (Ruby), Twisted (Python) и Node.js (V8).

Во вводном примере показан простой HTTP-сервер, прослушивающий порт 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();
4 голосов
/ 25 апреля 2009

У меня похожая проблема. Один вариант, который я нахожу интересным, - это использовать существующий сервер Comet, такой как cometd-java или cometd-python, в качестве основного центра сообщений. Тогда ваш PHP-код является просто клиентом для сервера Comet - он может публиковать или читать сообщения из каналов, как и другие клиенты.

Здесь есть интересный фрагмент кода: http://morglog.org/?p=22=1, который реализует часть этого метода (хотя есть и части кода отладки, которые также распространяются)

3 голосов
/ 18 ноября 2009

В настоящее время я реализую масштабируемый сервер PHP Comet с использованием функций сокетов. Это называется 'phet' ([ph] p com [et])

Страница проекта: http://github.com/Tim-Smart/phet

Бесплатно бесплатно присоединиться к разработке. В настоящее время мне удалось выполнить большую часть серверной логики, просто нужно завершить работу на стороне клиента.

РЕДАКТИРОВАТЬ: недавно добавленные возможности «многопоточности» с использованием метода pcntl_fork:)

3 голосов
/ 28 июля 2009

Вам будет трудно реализовать комету в PHP, просто из-за присущей ей однопоточности.

Извлечение Websync On-Demand - сервис позволяет вам интегрировать PHP через публикацию на стороне сервера, разгружать тяжелые параллельные соединения и позволит вам быстро создать приложение чата в реальном времени.

1 голос
/ 23 июня 2010

Вам нужно будет создать свой собственный сервер на PHP. Использование Apache / mod_php или даже fastcgi не будет масштабироваться вообще. Несколько лет, но вы можете начать:

PHP-Comet-сервер: http://sourceforge.net/projects/comet/

1 голос
/ 23 ноября 2009

Только что вышел новый модуль для веб-сервера nginx, который позволяет Comet использовать любой язык, включая PHP.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...