Как я могу сохранить скрипт в фоновом режиме — не работает

Я пытаюсь запустить файл chat-server.php Ratchet, который необходим для запуска сервера сокетов из php-файла, чтобы каждый раз, когда клиент посещал страницу, сервер запускался, но этого не происходило. Этот файл chat-server.php необходимо запустить с терминала, но я пытаюсь запустить его с главной страницы при посещении пользователя.

ФАЙЛОВАЯ СТРУКТУРА

./index.php

./config.php

./ vendor / (все файлы вендора)

./src/MyApp/Chat.php

./js/app.js

./inc/connect.php <- файл подключения к базе данных

./inc/send-message.php

./inc/startServer.php

./inc/bg.php

./inc/serverStatus.txt

./css/index.css

./css/reset.css

./bin/chat-server.php

config.php

<?php
include_once ("./inc/startServer.php");
?>

чат-server.php

<?php

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;if(isset($startNow)){

require dirname(__DIR__) . '/vendor/autoload.php';

$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);

$server->run();

}

?>

bg.php

<?php
$startNow = 1;
include_once ("../bin/chat-server.php");
?>

startServer.php

<?php

$statusFile = dirname(__FILE__).'/serverStatus.txt';
$status = file_get_contents($statusFile);
if($status == "0"){

function execInBackground($cmd) {
if(substr(php_uname(), 0, 7) == "WINDOWS") {
pclose(popen('start /B ' . $cmd, 'r'));
file_put_contents($statusFile, 1);
}
else {
exec($cmd . ' > /dev/null &');
file_put_contents($statusFile, 1);
}
}

execInBackground("php " . dirname(__FILE__) . "/bg.php");

}

?>

serverStatus.txt

Его значение по умолчанию было установлено на 0

НОТА: Обновил код соответствующим образом, но пока не работает.

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

-1

Решение

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

В твоем случае. Когда вы получаете доступ index.php и в том числе в нем config.php и с тех пор startServer.php это все нормально, потому что вы в том числе ./inc/startServer.php что правильно по отношению к index.php,
Но чем вы в том числе ../inc/serverStatus.txt, что не правильно, потому что вы все еще бежите index.php и этот относительный путь разрешается в /../inc/serverStatus.txt другими словами, вы пытаетесь получить доступ к файлу, который на один уровень выше вашего DOCUMENT_ROOT, Так что вы никогда не попадете в свой if заявление.
Вы можете использовать __FILE__ константа, которая всегда разрешает абсолютный путь текущий файл. Так что вы можете изменить свой $statusFile в

$statusFile = dirname(__FILE__) . '/serverStatus.txt';

Следующая вещь касается вас exec() а также popen(pclose()) команды. Если вы хотите выполнить какую-то команду, которой нет в вашем PATH переменная среды, чем вы должен укажите абсолютный путь к вашему файлу. Потому что вы не знаете, из какой папки он будет запущен. Это может быть начато с Apache home dir или, возможно, началось с домашнего каталога вашего пользователя. Это зависит от настройки вашего PHP это sapi модуль или это fcgi, В любом случае, вам нужно изменить свой execInBackground() в

execInBackground("php " . dirname(__FILE__) . "/bg.php");

И добавьте несколько пробелов в ваших командах, например так:

pclose(popen('start /B ' . $cmd, 'r'));
exec($cmd . ' > /dev/null &');

Таким образом, у вас не будет странных ошибок, которые могут произойти.

В вашем bg.php вам нужно изменить текущий рабочий каталог, например так:

<?php
$startNow = 1;
chdir(dirname(__FILE__));
include_once ("../bin/chat-server.php");
?>

Сюда, PHP найду chat-server.php неважно, из какой папки вы его запустите.

Кстати, как вы планировали остановить свой сервер? знак равно


ОБНОВИТЬ: Также у вас есть переменная область проблема в вашей функции execInBackground(), Ваша функция зависит от переменной $statusFile, но эта переменная определена в глобальный охват и не виден внутри функции. Чтобы сделать это видимым, вы должны включить заявление global $statusFile; в вашей функции до доступа $statusFile, Как это:

    function execInBackground($cmd) {
global $statusFile;
if (false !== stripos(PHP_OS, 'win')) {
pclose(popen('start /B ' . $cmd, 'r'));
file_put_contents($statusFile, 1);
} else {
exec($cmd . ' > /dev/null &');
file_put_contents($statusFile, 1);
}
}

и я изменил способ проверки ОС, потому что ваш подход содержал ошибку.


UPDATE2:

После нескольких тестов я выяснил, что когда php-скрипт работает в фоновом режиме (под Windows), он не может использовать «echo ()» для записи в STDOUT. Когда это произойдет, php-скрипт молча умрет, без ошибок. Так что поменяй все echo()в какой-то лог-функции.

Измените порт прослушивания на какой-то другой, это бесплатно, например, 50000. Потому что 8080 часто может быть уже занято некоторым веб-сервером или другим сервисом.

И запомни! Вы можете запустить свой чат-сервер, только если у вас есть собственный сервер (например, VPS / VDS или выделенный сервер) на публичный хостинг никто не позволит вам открыть какой-либо порт для входящих подключений по соображениям безопасности. На общедоступных серверах часто отключаются такие функции, как exec(), popen() и похожие по тем же причинам.

1

Другие решения

Я думаю, что вы должны прочитать http://php.net/manual/es/function.shell-exec.php

Обратите внимание, что эта функция отключена, когда PHP работает в безопасном режиме.

0

По вопросам рекламы [email protected]