Я создаю библиотеку , которая устанавливает соединение через сокет:
public function __construct(Options $options)
{
$this->responseBuffer = new Response();
$this->connection = stream_socket_client($options->fullSocketAddress());
if (!$this->isAlive($this->connection)) {
throw new DeadSocket();
}
stream_set_timeout($this->connection, $this->timeout);
$this->options = $options;
}
Отправка данных на сервер осуществляется методом send()
, который выглядит следующим образом:
public function send(string $xml)
{
try {
fwrite($this->connection, $xml);
} catch (Exception $e) {
$this->options->getLogger()->error(__METHOD__ . '::' . __LINE__ . " fwrite() failed " . $e->getMessage());
return;
}
}
Проблема в том, что catch
не фиксирует ошибки уведомления PHP, которые в моем случае являются показателем того, что само соединение разорвано.
В случае, если произошла ошибка сервера, я получаю <stream:error>
(стандарт XMPP), однако, если сломался сокет или произошел какой-то тайм-аут, как этот, я не могу его перехватить:
[22 мая 2019 12:35:07 UTC] Примечание PHP: fwrite (): сбой отправки 94 байтов с ошибкой = 110 Время ожидания соединения в ... / Socket.php в строке 52
В настоящее время я хотел бы знать, произошла ли ошибка, чтобы я мог инициировать переподключение, однако выполнение любого из этих действий не показалось полезным:
if (!is_resource($this->connection)) $this->reconnect();
if (!$this->connection) $this->reconnect();
Помимо проверки любого из свойств socket_get_status()
, поскольку socket_get_status($this->connection)['timed_out']
может иметь значение true
даже при активном соединении.
Есть ли способ поймать это уведомление?
Также есть ли способ имитировать поведение, чтобы я мог воспроизвести его, даже если время соединения не истекло?