Использование кометы с PHP?

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

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

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

11 ответов

Решение

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

апаш

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

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

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

Этот MPM пытается исправить "проблему поддержания жизни" в HTTP. После того, как клиент выполнит первый запрос, он может оставить соединение открытым и отправлять дополнительные запросы через тот же сокет. Это может сэкономить значительные накладные расходы при создании TCP-соединений. Однако Apache традиционно поддерживает весь дочерний процесс / поток в ожидании данных от клиента, что имеет свои недостатки. Чтобы решить эту проблему, этот MPM использует выделенный поток для обработки как сокетов Listening, так и всех сокетов, которые находятся в состоянии Keep Alive.

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

PHP

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

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

Редактировать:

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

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

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

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

PHP

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

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

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

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

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

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

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

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

Вы также можете попробовать 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();

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

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

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

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

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

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

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

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

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

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

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

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

Я думаю, что это больше проблема, потому что постоянно работает много потоков Apache. Это будет существовать с любым языком, если он работает через apache так же, как PHP (обычно).

Другие вопросы по тегам