php stream get contents зависает в конце потока

решение в конце вопрос

Я пишу приложение PHP, которое отправляет сообщение на сервер, а затем читает ответ в using stream_get_contents. Я общаюсь с тем же сервером в приложении для android таким же образом. Приложение android работает нормально и быстро реагирует, однако PHP зависает при чтении ответа с сервера.

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

stream_set_timeout($this->socket, 10); //10 seconds read timeout

while (!feof($this->socket)) {
    $breakOut = false;

    echo 'Reading response'.time().'<br/>';
    $data = stream_get_contents($this->socket, 5);
    echo 'Read response'.time().'<br/>';

    if ($data === false) {
        $this->latestErrStr = "Timed out waiting for a response.";
        return false;
    } else {
        $index = strpos($data, chr(3));

        if ($index !== FALSE){
            $breakOut = true;
            $data = substr($data, 0, $index);
        }

        $response .= $data;
    }

    $stream_meta_data = stream_get_meta_data($this->socket);

    //If we have no EOF marker then break if there are no bytes left to read
    if($breakOut || $stream_meta_data['unread_bytes'] <= 0) {
        break;
    }
}

вывод выглядит следующим образом:

Reading response1387463602
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463603
Reading response1387463603
Read response1387463623

как вы можете видеть, есть задержка 10s между последними двумя строками, но никакой заметной задержки между другими.

также для вашей информации я использую маркер ETX (3) для обозначения конца сообщения, поэтому я также останавливаюсь, если я нажму это, а не только конец поток.

Я делаю что-то не так? Есть ли лучший способ сделать это?

спасибо заранее...

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

Edit2: зависания были замечены до 40 секунд. Кажется, что он не фиксируется на 10 секунд, но странно, кажется, что это хорошие круглые числа каждый время.

решение (спасибо chathux):

stream_get_contents($stream, $bytes) будет блокировать, пока он не получит $bytes байт или тайм-аут истекает. Это означает, что мой код достиг конца и пытался прочитать 5 байтов (которых не существовало), поэтому он ждал 10s, прежде чем сдаться.

поскольку я знаю, что минимальный размер сообщения, возвращающегося ко мне, составляет 49 байт, я сначала прочитал эти 49 байтов (блокировка, пока я не получу их или 10S не истечет), чтобы заполнить stream_get_meta_data ' s

2 ответов


в документации говорится ,что " stream_get_contents () работает с уже открытым потоковым ресурсом и возвращает оставшееся содержимое в строке до байтов maxlength и начиная с указанного смещения."

поэтому, когда вы предоставляете 5 как maxlength, он будет читать только до пяти байтов и продолжит. если не читать до 5 байт он будет ждать и истекает через 10 секунд, которые вы упомянули в stream_set_timeout

пример :

//server side statement<br/>
$data = stream_get_contents($this->socket, 5);

//corresponding client code<br/>
fwrite($client, "1234");

в вышеуказанном случае сервер подожду, пока ты напишешь еще один байт. fwrite($client, "5");


Я предлагаю вам просто использовать , или даже