Веб-сокет сервер на PHP, запуск демона на PHP

В предыдущей статье о WebSocket-ах для самых начинающих я рассказывал больше о том, как настроить Денвер и убедиться в том, что всё работает, лишь чуть-чуть уделив время реализации простого ws echo сервера. Но если вы скачали архивы исходников, то, уверен, вы с лёгкостью разобрались в получении и отправке сообщений, чего вполне достаточно для использования технологии.
Рад тому, что в моём пока не раскрученном блоге пошла реакция и это побудило к тому, чтобы написать продолжение и раскрыть вопрос о том, как всё же заставить PHP скрипт ws сервера работать на хостинге, как следить за тем, что процесс запущен и PHP скрипт выполняется и не был закрыт по таймауту или при перезагрузке Apache, как избежать запуска дублирующего процесса PHP и ответы на другие необходимые вопросы, чтобы получить гарантированно работающий ws сервер. Обязательно создам Интернет ws echo сервер с функцией чата и размещу его на своём посредственном хостинге. Далее в этой статье PHP скрипт, который непрерывно выполняется на сервере и обеспечивает работу с ws я буду называть ws сервер, хотя фактически это процесс на стороне сервера. И самое важное, дам готовое решение даже для тех у кого нет SSH доступа к консоли хостингового сервера или виртуальной машины.

Сегодня будет много работы

Начнем с простого.

Размещение и запуск веб-сокет сервера на хостинге

Простота состоит в том, что именно с запуском никаких проблем нет. Вы можете взять PHP скрипт echows.php из прошлой статьи, совершенно ничего в нём не меняя, закачать на хостинг и обратиться к файлу из браузера, единственным отличием от выполнения в Денвере может быть то, что настройки Apache и кэширующих механизмов хостинга запрещают выводить информацию незавершенного PHP скрипта, в таком случае вы не увидите никакой информации в окне браузера, а страница продолжит грузиться в браузере. Но если попробуете подключиться к ws серверу из нашего ws клиента, то вы увидите что подключение прошло успешно и на ws echo сервер отвечает на все передаваемые запросы. В качестве адреса ws сервера в ws клиенте, естественно, нужно указать ws://yourdomain.com:8889. Как видите, всё в порядке. Единственная проблема с которой вы можете столкнуться это настройки файрволлов хостинга и занятость портов другими сервисами. Если у вас несколько доменов на одном IP адресе, то вы можете обращаться к ws серверу по адресу этого домена ws://anotheromain.com:8889 что, согласитесь не очень хорошо, особенно для хостинга где сотни веб-сайтов висят на одном домене, теоретически кто-то может использовать те же порты что и вы и это может привести к неработоспособности ws сервера, поэтому еще раз настоятельно рекомендую аккуратно выбирать порты и следить за тем, чтобы по прекращению работы ws сервер всегда закрывал все соединения и корректно закрывал сокеты. Теперь что касается самого PHP скрипта, как вы могли заметить, наш PHP скрипт живет только 100 секунд, после чего при попытке подключения или отправке сообщения, он закрывает все соединения и завершает своё выполнение. Как сделать так, чтобы он жил «вечно»? Есть достаточное количество методов. Но проблема не в том, что PHP скрипт должен выполняться бесконечно, а проблема в том, как обеспечить корректное завершение работы скрипта в различных ситуациях и затем коректно возобновлять его работу. Например, при выключении сервера и последующем его включении PHP скрипт сам не запустится, а отслеживать работает ли ws сервер и если не работает в ручную его запускать, очень плохая идея.

Метод бесконечного выполнения PHP скрипта запуск из браузера

Первое что нужно сделать, это в самом скрипте указать безлимитное время жизни PHP сценария set_time_limit(0); и игнорирование отключения браузера ignore_user_abort(true); чтобы PHP скрипт выполнялся после того, как вы закроете окно браузера. Когда вы произвели необходимые действия можете запускать его из браузера. Проблема в том, что запустив его однажды, мы не сможем проверить, всё ли в порядке с процессом, не возникло ли ошибок по ходу выполнения, а продолжает ли скрипт работу или нет можно убедиться только подключившись к нему ws клиентом. Конечно, можно добавить в этот скрипт функционал ведения лог-файла, в котором будут зафиксирована история его работы. Также при перезагрузке Apache на хостинге процесс со скриптом 100% будет выключен. Этот способ может подойти только в случае, когда мы закачиваем на сервер гарантированно работающий отлаженный ws сервер PHP скрипт и нам важно чтобы он работал только короткое обозримое время в зависимости от надежности хостинг провайдера, но этот метод совершенно не применим для работы полноценного промышленного ws сервера из-за своей крайней ненадёжности и невозможности отключения в тот момент когда нам это нужно. Представьте ситуацию, что администратор хостинг сервера решил перезагрузить Apache с целью обновления, а вы не проверяете постоянно работает ваш ws сервер или нет, а пользователи тем временем допустим сидят в вашем чате, и внезапно всё ложится, пользователи негодуют. Опять же, можно применить пару костылей, прежде чем ws клиент будет подключаться к ws серверу по протоколу ws, заставить ws клиент обращаться к другому серверному PHP скрипту по XMLHttpRequest(), и требовать от проверку запущенности ws сервера. Метод немного костылеватый, но имеет место в непромышленных решениях вроде небольшого чата или маленькой игрушки. Именно его я и использую в своих небольших проектах.

На всякий случай провел эксперимент, запустил ws сервер на хостинге предварительно внеся в PHP скрипт механизм закрытия всех соединений и прерывание процесса при получении сообщения «OFF» от клиента. Не трогал несколько дней, периодически отправляя разные сообщения и проверяя живучесть, отправил команду «OFF» спустя приблизительно два дня ws удачно завершил свою работу, время жизни процесса ws сервера оказалось 183 403 секунды (2 с небольшим суток) и думаю что он мог бы проработать еще дольше без всяких проблем.

Метод бесконечного выполнения PHP процесса запуск из консоли

В принципе, различие с запуском PHP скрипта из браузера практически отсутствует, за исключением того, что все данные о работе PHP скрипта выводятся в консоль и еще несколько небольших нюансов. Сам PHP скрипт также должен содержать set_time_limit(0); и ignore_user_abort(true);. Запуск PHP скрипта из *nix консоли осуществляется командой $ php -q scriptfile.php (для подключения к консоли я использовал Putty). Ключ -q (—no-header) обозначает что процесс должен быть запущен в тихом режиме и подавляет вывод заголовков HTTP которые обычно отправляются браузеру. $ man php позволит посмотреть другие интересующие ключи. Отличная документация на официальном сайте PHP которая помогла не только разобраться с запуском PHP скриптов из консоли, но и позволила внести существенные улучшения в сам PHP скрипт. Обратите внимание, что вы можете перенаправить вывод результатов выполнения скрипта в любой файл на сервере, используя символ ‘больше’ (‘>’), как обычно я и поступаю

$ php -q scriptfile.php > scriptfileoutput.txt 

PHP может быть использован для запуска PHP-скриптов в абсолютной независимости от Apache, но у меня нет уверенности что без Apache будет работать механизм сокетов, я не пробовал запускать без Apache — мне это показалось не к чему. Запуск через консоль считается более правильным нежели через веб-браузер, но он также как и запуск через браузер не способен решить ряд проблем. Возможно такой запуск и избавит нас от прекращения работы скрипта при перезапуске Apache и то это маловероятно, но что делать, если весь веб-сервер или виртуальная машина будет перезагружена. Вам придётся в ручную лезть на сервер и запускать скрипт, конечно если у вас большой игровой проект и есть выделенные системные администраторы которые мониторят состояние процессов на сервере и есть скрипты инициализации и загрузки ws сервера вместе с Apache и всем остальным, в таком случае это единственно правильный вариант, но мы говорим о бытовом удобном способе реализации ws сервера на PHP для небольших проектов. Также иногда встречается проблема при запуске PHP скрипта из консоли, которая прекращает выполнение PHP скрипта одновременно с тем когда вы выходите из консили, это связано с тем что выполнение PHP скрипта было привязано к вашей сессии как к клиенту. По идее это должно залечиваться использованием в PHP скрипте строки ignore_user_abort(true);, но это помогает не всегда в связи с разными настройками PHP. В таком случае используют трюк, давая PHP скрипту поток /dev/null, который он будет считать клиентом и не прекратит работу при вашем выходе из консоли.

$ php -q scriptfile.php < /dev/null > scriptfileoutput.txt &

Амперсанд в конце обязателен, чтобы вы могли нажать Ctrl+C и вернуться в консоль а процесс остался в памяти. Или можно воспользоваться утилитой nohup.

В добавок, будет полезно знать, что и на windows-платформе можно запускать выполнение скрипта из консоли

> w:\usr\local\php5\php.exe -q w:\home\localhost\www\echows.php

Если всё делать правильно, то лучше воспользоваться утилитой Supervisor: A Process Control System она следит за работой процесса, в случае необходимости запускает его, осуществляет регистрацию падений. Отличная правильная вещь, когда вы делаете серьезный проект и в вашем распоряжении выделенный сервер или хотя бы VDS.

ws сервер управление процессом PHP из браузера

В результате изучения способов запуска PHP скриптов у меня родилась очень простая идея — реализовать на стороне ws клиента перед подключением к ws серверу запрос XMLHttpRequest() к PHP скрипту который проверяет статус процесса ws сервера и если он не запущен запускает. Также возникла идея реализовать что-то вроде страницы администратора ws сервера, на которой будет доступен лог последних событий: о том когда был запущен, почему упал, кто инициировал последующий запуск и др., с которой можно будет дать команду ws серверу перезапуститься, выключиться, закрыть все соединения и др.

Какой должен быть интерфейс для ws клиента:

  • Проверка состояния ws сервера и запуск, если сервер недоступен

Какой должен быть интерфейс для ws администратора:

  • Информация о статусе ws сервера, желательно с количеством подключений и объёмом занимаемой памяти
  • Просмотр журналов
  • Остановка работы ws сервера
  • Перезагрузка ws сервера

Итак, для реализации нам нужен ws сервер, который необходимо повесить в памяти одним из описанных ранее способов, т.е. нужно сделать из него качественного демона. Отличная статья относительно процессов и демонов есть на хабре. Однако, к сожалению, найти хостинг с поддержкой команды создания дочерних процессов на PHP pcntl_fork еще труднее чем с поддержкой сокетов, поэтому придётся отказаться от классического способа демонизации. Также такие программы невозможно отладить на windows т.к. forkи существуют только в *nix операционных системах. Но всё же кое что полезное из статьи почерпнуть удалось, а именно создание PID-файла хранящего process id, который не позволит запускаться двум процессам одновременно — подробнее об этом чуть ниже.

В итоге я немного модифицировал код PHP скрипта ws echo сервера вместив в него код переключения потоков ввода/вывода STDIN, STDOUT, STDERR и, тем самым, упростил запуск ws сервера из консоли:

$ php -q /home/path/echows.php &

Получил хорошо работающий демон echows.php (архив с клиентом, версия без мониторинга) и без использования pcntl_fork. Он запускается через консоль, отвязывается от консоли и всё замечательно отвечает на все запросы пользователей по адресу ws://yourdomain.com:8889, и корректно закрывается при отправлении сообщения «OFF». Но вот незадача, не удаётся проверить запущен ли демон или нет и тем самым избежать дублирующего запуска демона. Да, при запуске создаётся файл pid_file.pid, который хранит process id (уникальный номер процесса в системе OS *nix) нашего демона а при корректном завершении работы демона, например, при получении сообщения «OFF», этот файл удаляется. При запуске можно конечно проверять наличие этого файла, и если файл есть, то сообщать о том что демон уже запущен и таким образом избегать дублирующего запуска, но что делать если демон завершил свою работу некорректно и не удалил файл pid_file.pid, в таком случае наш демон никогда больше не запустится. Опять же на хабре удалось найти отличную функцию проверки наличия демона.

function isDaemonActive($pidfile) {
if( is_file($pidfile) ) {
$pid = file_get_contents($pidfile);
//проверяем на наличие процесса, функция posix_kill может быть устаревшей возможно потребуется замена при переходе на PHP 5.3+
if(posix_kill($pid,0)) {
//демон уже запущен
return true;
} else {
//pid-файл есть, но процесса нет
consolemsg("there is no process with PID = ".$pid.", last termination was abnormal...");
consolemsg("try to unlink PID file...");
if(!unlink($pidfile)) {
consolemsg("ERROR");
//не могу уничтожить pid-файл. ошибка
exit(-1);
}
consolemsg("OK");
}
}
return false;
}

И опять проблема в том, что функция posix_kill($pid,0) оказалась не работоспособной по той же причине что и pcntl_fork. Я не смог с этим мириться и опять разработал «хитрое» решение. Т.к. я всё равно задумал реализовывать функционал показывающий состояние ws сервера, то мне так или иначе потребуется функция которая показывает статус процесса в ОС. Для реализации этой функции воспользуемся командой exec() которая позволяет выполнять любые команды консоли. И если мы выполним

exec("ps -aux -p ".$pid, $output); 

то в результате в массив $output, в случае если демон запущен и имеет $pid будет выдана информация о демоне (процессе).

USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
aow 62335 0.3 0.1 120080 16020 ?? SJ 4:31PM 0:00.02 php -q echows.php

Таким образом получили реально работающие функции без posix_kill, которые проверяют запущен ли демон и выдают данные о нём соответственно.

Upd 2017.08.14: В примере выше используется BSD синтаксис команды ps. Для большинства *nix систем он будет отличным, а эта команда будет выводить все процессы вместо одного с идентификатором pid. Начиная с версии ws server admin panel v.0.4. и выше используется классический синтаксис, корректно работающий в большинстве *nix систем.

function isDaemonActive($pidfile) {
if( is_file($pidfile) ) {
$pid = file_get_contents($pidfile);
//получаем статус процесса
$status = getDaemonStatus($pid);
if($status['run']) {
//демон уже запущен
consolemsg("daemon already running info=".$status['info']);
return true;
} else {
//pid-файл есть, но процесса нет
consolemsg("there is no process with PID = ".$pid.", last termination was abnormal...");
consolemsg("try to unlink PID file...");
if(!unlink($pidfile)) {
consolemsg("ERROR");
//не могу уничтожить pid-файл. ошибка
exit(-1);
}
consolemsg("OK");
}
}
return false;
}

function getDaemonStatus($pid) {
$result = array ('run'=>false);
$output = null;
exec("ps -aux -p ".$pid, $output);

if(count($output)>1){//Если в результате выполнения больше одной строки то процесс есть! т.к. первая строка это заголовок, а вторая уже процесс
$result['run'] = true;
$result['info'] = $output[1];//строка с информацией о процессе
}
return $result;
}

Теперь когда функция проверки состояния готова, мы можем запускать демона не из консоли а выполняя команду PHP exec(«php -q echows.php &»); и выключать демона сообщением OFF.
Последнее что нужно изменить в ws echo сервере и ws клиенте добавить перед подключением AJAX запрос серверу, который бы его поднимал, в случае если он лежит. Теперь нам не нужно думать о том, в каком состоянии находится демон, т.к. знаем что даже если сервер перезагружался, клиент при первом же обращении его поднимет.

Браузерная панель управления ws сервером

Разработаю простую систему управления и мониторинга демона. Она очень проста и состоит из нескольких файлов echowsadmin.html (панель администратора), echowsadmin.js (логика панели администратора), echowsadmin.php (логика управления ws echo сервером). Разработать эту систему оказалось на удивление просто, я потратил не более 1го часа своего времени.

Для того, чтобы любой пользователь не мог выключить демона командой OFF, я убрал этот функционал из PHP кода ws echo сервера. Соответственно, реализовав функцию выключения из системы управления демоном. Реализация не самая изящная, вместо сигналов я использую файл off_file.pid, но зато гарантированно не требуется никаких дополнительных библиотек и выключение происходит корректно. Т.к. на ws сервере цикл while повисает в моментах слушания сообщений сокета, то после создания off_file.pid нужно соединиться с ws сервером чтобы он дошел до конца цикла и проверил наличие off_file.pid, для этого делаю небольшую хитрость, имитирую подключение по сокету из echowsadmin.php и ввожу некоторую задержку чтобы всё сработало и скрипт сообщил о благополучном завершении работы. Скачайте архив разработанной системы управления, ws сервера и клиента (устаревший архив, более новый в Downloads), не забудьте указать адрес расположения файла echowsadmin.php на вашем хостинге в echowsadmin.js в строке 10, адрес echowsstart.php в socket.js и адрес ws сервера в echowsadmin.php (вернее не адрес, а порт, т.к. файл должен находиться на сервере то адрес всегда будет 127.0.0.1), куда будет пытаться подключиться наш одноклеточный мини клиент при выключенном ws echo сервере. Кнопку перезапуска ws echo сервера я делать не стал, так как понятно, что для этого нужно нажать stop, а затем start и необходимость этого действия в одной кнопке практически отсутствует. Вся эта система управления работает только под управлением *nix операционных систем, т.е. на хостинге. А вот так она выглядит.

Панель управления демоном

Панель управления демоном

Очевидно, что можно много чего улучшить:

  • Улучшить представление и сделать более детальной информацию о статусе ws сервера
  • Добавить вывод в лог более подробной информации о занимаемой памяти и количества текущих соединений
  • Сделать проверку на операционную систему и разработать версию для Денвера и Windows
  • Сделать авторизацию

Но, в моём случае стояла задача сделать себе простенький инструмент мониторинга состояния демона через веб. Кстати, эту штуку слегка модифицировав можно использовать для мониторинга любого демона, а не только ws.

А что касается реализации для ОС Windows, то все места где pid можно обходить проверкой и таким образом обеспечиь запускаемость.

if (strtoupper(substr(PHP_OS,0,3)) === 'WIN') { 

}

А запущен демон или нет достаточно проверять просто наличием pid файла.

Пока я был на выходных, забыл выключить ws echo сервер, в итоге время его жизни составило 233774 секунд, т.е. где-то около 3х суток, занимаемая память так и осталась около 0.1%, что говорит о том, что решение имеет право на жизнь.

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

Мои статьи про PHP демонов и веб-сокеты

  • Shone_dz

    Приветствую! А можно ли привести пример хостинга на котором echows.php поднимится и будет отвечать клиенту socket.html. Попытки поднять на 4-х разных хостингах потерпели неудачу. Локально все работает. При этом, при попытке прервать echows.php и запустить его снова, сокет не открывается с сообщением о том, что порт уже занят. Следовательно насколько могу понять, если ошибок у echows.php нет, но и соединения от клиента так же нет, значит хостинги закрывают входящие соединения по нестандартным портам.

    • Да, действительно, очень похоже именно на это. Вы же, надеюсь, используйте порт из диапазона 1024+? Думаю что следует написать письмо в техподдержку хостинговой компании и вопрос разрешится.

      В моём конкретном случае я использую VDS на hoster.ru. Но я бы рекомендовал лучше hetzner.de vq7 за 8 EUR.

      • Shone_dz

        Списывался с суппортом одного из хостингов, все порты кроме 80-го закрыты на входящие соединения, посоветовали купить у них же VDS. Спасибо за ссылку.

      • Roma Makarov

        при попытке reconnect выдает 403 get, свидительствует ли это о том, что порт закрыт? в админке сервер запускается

  • Andrew Kotov

    Очень полезная статья для новичков. Но есть проблемы для адаптации этого кода с localhost на хостинг или даже виртуальный домен.

    • А какого рода проблемы?

      На всякий случай посмотрите финальную версию админки — она есть в статье
      http://petukhovsky.com/simple-web-socket-on-php-developing-and-testing/

      • Andrew Kotov

        Проблему разрешил, чуть чуть подправив пути до скриптов. Еще бы было классно довести эту работу до чата с возможностью отправлять сообщение приватно одному кому-то, тогда это уже будет почти полноценная система мгновенных сообщений, как в соц сетях.

  • Николай Приймак

    у меня не работает((
    [2014.11.18-11:28:18]console — start

    [2014.11.18-11:28:18]echows — try to start…

    [2014.11.18-11:28:18]OK getmypid = 25286

    [2014.11.18-11:28:18]socket — try to start…

    [2014.11.18-11:28:18]ERROR socket unavailable Address already in use(0)

    [2014.11.18-11:28:18]pidfile /var/www/тут мой сайт.ru/pid_file.pid ulinked

    [2014.11.18-11:28:18]console — end

    • ERROR socket unavailable Address already in use(0)

      это ошибка означает что данный порт уже используется.

  • Николай Приймак

    Спасибо все работает!

  • Николай Приймак

    Только одно но! почему сообщения приходит только в то окно где оно была отправлена а не во все открытые подключения(окна браузера)?

    • Потому что это echo сервер а не чат.

      Чат рассмотрен в следующей статье http://petukhovsky.com/simple-web-socket-on-php-chat/

      • Николай Приймак

        может подскажете что подправит в этом скрипте? а то в том слишком не понятный для меня стиль кода на классах(((

        • Николай Приймак

          просто я хочу сделать чат для своей игры с комнатами)) скрипт чтобы создават комнаты я уже поправил и комнаты создает!) но что все работало нужно что сообщения рассылались всем ко подключен к сокетам! помогите мне умаляю!!!

          • Рекомендую использовать готовый код чата из следующей статьи. Но в коде, в любом случае придётся разобраться, чтобы привязать авторизованного пользователя вашей игры к веб-сокет серверу.

          • Николай Приймак

            С авторизацией я уже все сделал по другому через аджар запросы

            вот что я накапал в вашем чате

            foreach($this->connects as $cnt) //обрабатываем все соединения
            fwrite($cnt, $this->encode($msgtosend));//echo функция ответа

            вот это отвечает за рассылку всем подключенным?

          • Да, этот код рассылает по всем открытым соединениям.

            Не уверен, что вы сделали авторизацию на ws-сервере. Поясню. Вы вошли в игру, авторизовались в игре, но когда вы пишете в чат, вы делаете это без авторизации и к этим портам вашего чата может подключиться любой пользователь даже не зарегистрированный в игре.

            Для того, чтобы реализовать авторизацию на ws, нужно проделать следующее. Передавать клиенту (браузеру) авторизационные данные игрока, чаще всего это одноразовый ключ получаемый по AJAX. Далее по этому ключу клиент (браузер) авторизуется на ws. Причем этот ключ должен быть известен и самому ws. Для этого ws требуется модернизовать и подключить к базе для возможности проверки ключа полученного от клиента.

          • Николай Приймак

            Ага понятно! спасибо за совет но мне это не нужно пока, я же не мега хит делаю который школьники будут пытаться хакнуть)))

          • Николай Приймак

            Спасибо за скрипты!

  • Вот еще русскоязычная статья по демонам http://plutov.by/post/php_daemons

  • Все хорошо, большое спасибо за статью!
    Но, пока в функции создания сокета не поменял 127.0.0.1 на внешний IP-адрес соединиться с echows.php демоном не получалось.

    Наверное стоит указать, что все-таки при размещении этого добра на хостинге открывать сокет нужно на внешнем сетевом интерфейсе, иначе обратиться к 127.0.0.1 извне невозможно ведь.

    • Да, обратил внимание только через два года когда переезжал на новый VDS. Действительно лушче ставить 0.0.0.0, на старом VDS видимо в iptables был форвардинг.

  • Artem Komin

    Блин, я не могу понять как происходит отправка определенному пользователю. Можно конечно играться с эхо серваком, но толку от этого. Как сервер отправляет сообщение именно не всем, а какому -то одному пользователю из всех находящихся на сайте? Статья хорошая.

  • евгений терехов

    Работает автозапуск по обращению клиента! Но страница администрирования никак не реагирует. Все время пишет, что сервер остановлен, никакой инфы не появляется. При этом также ничего не записывается в ТХТ. Возможно ли, что прав на запись файлов-маркеров недостаточно у пользователя?

    • Конечно возможно

      • евгений терехов

        Пока плохо разбираюсь в теме, поэтому позволю себе такой вопрос… А какому пользователю нужно давать права на операции с этими файлами и какой уровень прав будет достаточен?

        • Нужно давать пользователю от которого запускается php и собственно сам скрипт. В принципе можно не заморачиваться и для простоты на TXT файл сделать chmod 777 filename.txt

          • евгений терехов

            А можно ли сделать chmod 777 на файл, которого не существует или который постоянно создается-удаляется?

          • Дайте права скрипту на каталог.

  • frolovand

    Добрый день!
    Все работает, настроил под свои нужды, но примерно раз в 2 суток, зависает
    зависает так что надо удалить флаги, потом можно перезапустить

    Можете подсказать куда копать?
    Апач не ребутался

    • Посмотрите как зависает. Перестаёт отвечать но висит в памяти? Посмотрите по логам в ws admin server panel (собственнописная утилитка, последняя версия в следующей статье) что с памятью. Но, по правде с такой проблемой не приходилось сталкиваться, скрипт чата работал по нескольку недель между ребутами самого сервера.

      • frolovand

        в пямяти его нет, но и завершился не корректно, так как флаг остался

        Вы не изменяли настройки php.ini ? все на стандартных?

        • Да, всё на стандартных. Странно, что-то рубит процесс или возникает какая-то ошибка, хотя странно, возникала бы раньше.