Всем добрый день! C Websocket`ами ранее не работал, но вот появилась в них необходимость...Есть у меня websocket, который тянет данные с биржи (получается я выступаю в качестве клиента). Эти данные передаются часами, намеренно соединение никогда не закрывается. Но иногда скрипт останавливается спустя там 10, 20 часов по неизвестным причинам(может сам сервер прекратил работу, может мой клиент где-то затупил). Суть самого вопроса: Можно ли как-то отследить, что соединение до сих пор открыто или что скрипт еще отрабатывается? Если связь по вебсокету прервана, то нужно его перезапустить. Дайте пожалуйста совет, как это правильно делается.
Использовался https://github.com/Devristo/phpws Код подключения: PHP: <?php define('ROOT', dirname(__FILE__)); require_once(ROOT.'/vendor2/autoload.php'); // Composer autoloader require_once (ROOT.'/pushService/Bitfinexpush.php'); $loop = \React\EventLoop\Factory::create(); $logger = new \Zend\Log\Logger(); $writer = new Zend\Log\Writer\Stream("php://output"); $logger->addWriter($writer); $client = new \Devristo\Phpws\Client\WebSocket("wss://api.bitfinex.com/ws/2", $loop, $logger); $bitfinex = new Bitfinexpush(); $client->on("request", function($headers) use ($logger){ $logger->notice("Request object created!"); }); $client->on("handshake", function() use ($logger) { $logger->notice("Handshake received!"); }); $client->on("connect", function($headers) use ($logger, $client){ $logger->notice("Connected!"); $client->send('{"event":"subscribe","channel":"candles","key":"trade:5m:tBTCUSD"}'); }); $client->on("message", function($message) use ($client, $logger){ $msg = $message->getData(); $bitfinex->getData($msg); }); $client->open(); $loop->run();
попробуй посмотреть метод getState() ну или подпишись на чего-нить такое PHP: $client->on("close", function($message) use ($client,$logger){ });
Да, всё верно, такой метод есть. Можно проверять типа: PHP: if($client->getState() == 2){ $client->open(); } Это в том случае, если сервер мне закрыл соединение... А вот если скрипт к примеру завершился ошибкой, как его заново запустить? Смотрю сейчас в сторону этого. Чтобы крон к примеру каждый час проверял, и по надобности перезапускал скрипт. PHP: $lockFile = __FILE__.'.lock'; $hasFile = file_exists($lockFile); $lockFp = fopen($lockFile, 'w'); // Если блокировку получить не удалось, значит второй скрипт еще работает if (!flock($lockFp, LOCK_EX | LOCK_NB)) { die('Sorry, one more script is running.'); } // Если файл блокировки уже существовал, но не был залочен, // значит предыдущий запуск завершился некорректно if ($hasFile) { echo 'The previous running has been completed with an error.'; } // Все в порядке, блокировка lock получен // По окончании работы необходимо снять блокировку и удалить файл register_shutdown_function(function() use ($lockFp, $lockFile) { flock($lockFp, LOCK_UN); unlink($lockFile); }); Такой подход еще актуален? или возможно есть новые методики уже?
чет велосипед какой то с файлами то... в каком смысле скрипт завершился? Исключение какое то сработало? или че - может в эту сторону копать?
Да, по поводу велосипеда согласен) просто ничего адекватного больше не нашел... Нет, исключений нет. На данном этапе я явно понимаю, что мне сам сервер оборвал соединение, в этом случае решение с методом getState() вполне подходит. Но заглядывая немного наперед, возможен же такой момент, что к примеру сервер к которому я обращаюсь за данными вовсе не отвечает, упал на какое-то время. И в этой ситуации скорей всего getState я не получу, верно? Как тогда можно перезапускать скрипт до того момента, пока сервер мне не ответит?
запусти на локалке - отруби инет и посмотри че будет) --- Добавлено --- именно с этой библой не работал, но на ratchet когда делал, а клиента на js там явно всегда срабатывало onclose .... просто код завершения менялся типа например 1000 был - некорректное завершение - тогда по таймеру запускали проверял а при другом статусе - который обозначал что серв сам корректно просто со мной завершил сеанс - типа выдавал сообщение - что сервер недоступен и кнопель- попробовать еще - ну а там все ясно
Гениально)) Да, сработало исключение Код (Text): 2017-11-09T16:50:59+03:00 ERR (3): exception 'RuntimeException' with message 'Unable to connect to DNS server: Да тут тоже есть статусы есть 0,1,2,3. 1 - соединение установлено, 2 - соединение закрыто, 3 - соединение еще не установлено. Это как я понял. Вот меня этот тонкий момент и интересует. У вас к примеру кнопка была, чтобы переподключиться, а вот как бы мне переподключаться? Можно к примеру отлавливать исключение, что сервер лежит сейчас, и опять перезапускать скрипт. Но тогда получится что я так сказать "в рекурсии" будут гонять этот скрипт и бессмысленно ломиться на сервер часами... sleep на некоторое время делать что ли, чтобы хоть раз в 5 минут делать подключение? Или это в корне не правильное решение?
ну не знаю....... я бы постепенно увеличивал интервалы просто типа через минуту, еще минуту, 5, 10,20, час , сутки )))