borzih2
Новичок
Демон чата: PHP или C ???
Прошу прощения, что затрагиваю частую тему, но хорошего ответа пока найти не удалось...
На каком языке делать демона? PHP или C? Очень хотелось бы на PHP. И код писать проще (а значит ошибок меньше допускать), и с MySQL легко связываться, но вопрос "производительности" заставляет задуматься...
Был создан "тестовый демон" на PHP. При нагрузке в 100 онлайн пользователей - 75% загрузки процессора (Intel Pentium IV 3000 МГц). Расход памяти - несколько мегабайт. В основе кода лежит примерчик от young (Alexander Voytsekhovskyy). Вот полный текст кода:
Нет ли в этом коде какой-нибудь страшной ошибки, из-за которой возникает такая страшная загрузка процессора лишь при 100 пользователях ???
Прошу прощения, что затрагиваю частую тему, но хорошего ответа пока найти не удалось...
На каком языке делать демона? PHP или C? Очень хотелось бы на PHP. И код писать проще (а значит ошибок меньше допускать), и с MySQL легко связываться, но вопрос "производительности" заставляет задуматься...
Был создан "тестовый демон" на PHP. При нагрузке в 100 онлайн пользователей - 75% загрузки процессора (Intel Pentium IV 3000 МГц). Расход памяти - несколько мегабайт. В основе кода лежит примерчик от young (Alexander Voytsekhovskyy). Вот полный текст кода:
PHP:
<?
// **************************************************************************
// Основные константы
// **************************************************************************
define("HOST", "111.222.33.44"); // Хост (IP) для прослушки
define("PORT", "1234"); // Прослушиваемый порт
define("DALAY", 100000); // Кол-во милесекунд между проверками
define("MAX_KEEP_ALIVE", 600); // Макс. время, позволенное быть без активности
// **************************************************************************
// Класс, занимающийся обработкой конкретного клиента
// **************************************************************************
class phpServerThread {
// Минимальная информация, необходимая для описания одного клиента
// ---------------------------------------------------------------
var $socket; // Сокет соединения
var $buffer; // Временный буфер для чтения команд
var $lastActivity; // Время последней активности клиента
// Конструктор клиента (вызывается в момент его коннекта)
// ------------------------------------------------------
function phpServerThread($socket) {
$this->socket = $socket; // Запоминаем сокет
$this->buffer = ''; // Обнуляем буффер
$this->lastActivity = time(); // Дата активности
$this->response("Hello, user!"); // Отправляем ответ пользователю
}
// Отправить клиенту сообщение. $mess - текст сообщения.
// -----------------------------------------------------
function response($mess) {
//$mess = str_replace("\n","",$mess);
//$mess = str_replace("\x00","",$mess);
$mess = $mess."\n\x00";
socket_write($this->socket, $mess, strlen($mess));
}
// Уничтожить клиента
// ------------------
function destroy() {
@socket_close($this->socket);
}
}
// **************************************************************************
// Начальная инициализация
// **************************************************************************
$sock = socket_create(AF_INET, SOCK_STREAM, 0) or die("Error");
socket_bind($sock, HOST, PORT) or die("Error");
socket_listen($sock, 20) or die("Error");
socket_set_nonblock($sock) or die("Error");
$pool = array();
echo "Demon is started!\n";
// **************************************************************************
// Вечный цикл прослушки
// **************************************************************************
while(1) {
usleep(DELAY);
// Принимаем клиентов, которые стоят в очереди
$currentTime = time();
if(($msgsock = @socket_accept($sock))) {
socket_set_nonblock($msgsock);
$pool[] = & new phpServerThread($msgsock);
echo "New client is connected! Number of clients: ".count($pool)."\n";
}
// Обслуживаем клиентов
foreach($pool as $key => $client) {
// Читаем все что они хотят сказать
if($tmp = @socket_read($pool[$key]->socket, 1024)) {
$pool[$key]->buffer .= $tmp;
$pool[$key]->lastActivity = $currentTime;
}
// Если в буфере есть законченая фраза - обрабатываем
if($pos = strrpos($pool[$key]->buffer, "\n")) {
$toSay = substr($pool[$key]->buffer, 0, $pos);
$pool[$key]->buffer = substr($pool[$key]->buffer, $pos + 1);
echo "User command is: ".$toSay."\n";
user_command($key, $toSay);
}
// Соединение завершено клиентом ИЛИ превышено время ожидания?
if($tmp==="" || $currentTime - $pool[$key]->lastActivity > MAX_KEEP_ALIVE) {
$pool[$key]->destroy();
unset($pool[$key]);
echo "Client is DIE! Number of clients: ".count($pool)."\n";
}
}
}
// **************************************************************************
// Функция обработки команд от Флешки
// **************************************************************************
// $client - клиент, который подал команду
// $command - текст команды
function user_command($client, $command) {
global $pool; // Тут живут клиенты
$a = 2*(int)$command;
$pool[$client]->response($a);
}
?>