Note that there are some explanatory texts on larger screens.

plurals
  1. POphp stream_get_contents hangs at the end of the stream
    primarykey
    data
    text
    <blockquote> <p><strong>Solution at the end of the question</strong></p> </blockquote> <p>I am writing a PHP application that sends a message to a server and then reads a response back in using <code>stream_get_contents</code>. I communicate with the same server in an android app in the same way. The android app works fine and responds quickly, however the PHP hangs when reading the response back from the server.</p> <p>In the code sample below, I have set a tiny buffer size of 5 bytes to test a theory. If I remove this buffer size it hangs, however with the 5 byte size it only hangs on the last pass through the loop:</p> <pre><code>stream_set_timeout($this-&gt;socket, 10); //10 seconds read timeout while (!feof($this-&gt;socket)) { $breakOut = false; echo 'Reading response'.time().'&lt;br/&gt;'; $data = stream_get_contents($this-&gt;socket, 5); echo 'Read response'.time().'&lt;br/&gt;'; if ($data === false) { $this-&gt;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-&gt;socket); //If we have no EOF marker then break if there are no bytes left to read if($breakOut || $stream_meta_data['unread_bytes'] &lt;= 0) { break; } } </code></pre> <p>The output is as follows:</p> <pre><code>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 </code></pre> <p>As you can see there is a 10s delay between the last two lines, but no noticeable delay between the others.</p> <p>Also for your information I use an ETX marker (3) to signify the end of a message, so I also stop if I hit this rather than just the end of the stream.</p> <p>Am I doing something wrong? Is there a better way of doing this?</p> <p>Thanks in advance...</p> <p>Edit: Just to be clear, the above code is only expecting one message response. It does not care about any data that comes back after it has received an ETX byte.</p> <p>Edit2: Hangs have been seen of up to 40 seconds now. It doesn't appear to be fixed to 10 seconds, but it weirdly seems to be nice round numbers every time.</p> <p><strong>Solution</strong> (thanks to chathux)<strong>:</strong></p> <p><code>stream_get_contents($stream, $bytes)</code> will block until it receives <code>$bytes</code> bytes or the timeout expires. This means my code was reaching the end and trying to read 5 bytes (which didn't exist), it was therefore waiting 10s before giving up.</p> <p>As I know the minimum size of a message coming back to me is 49 bytes, I first read those 49 bytes (blocking until I get them or 10s expires) in order to populate the <code>stream_get_meta_data</code>'s <code>unread_bytes</code> field. Once I have this I dynamically adjust the buffer size to <code>min(16*1024, unread_bytes)</code> so I either read 16k at a time or all of the remaining bytes, whichever is smaller. In my case this usually only means two goes through the loop as messages are often tiny (49 bytes + payload).</p> <p>The system now hangs for approximately 3 seconds instead of 10, but it hangs waiting for the initial few bytes to arrive (rather than at the end) which can be put down to network latency and other normal factors.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload