diff --git a/src/Socket/AbstractSocket.php b/src/Socket/AbstractSocket.php index 91b0aee4..fbeb8874 100644 --- a/src/Socket/AbstractSocket.php +++ b/src/Socket/AbstractSocket.php @@ -56,6 +56,13 @@ abstract class AbstractSocket extends Configurable implements ResourceInterface */ protected $name; + /** + * Whether we have ran fread() on the socket at least once. + * + * @var bool + */ + private $hasBeenFreadInitialized = false; + /** * Gets the IP address of the socket. * @@ -242,8 +249,22 @@ public function receive(int $length = self::DEFAULT_RECEIVE_LENGTH): string return $buffer; } - - $result = \fread($this->socket, $length); + if (!$this->hasBeenFreadInitialized) { + // stream_select() may erroneously return 0 before the first fread() (observed on PHP8.4.12 Ubuntu24.04 chrome-php/wrench1.8.0) + $this->hasBeenFreadInitialized = true; + $selectResult = 1; + } else { + $readArray = [$this->socket]; + $writeArray = null; + $exceptArray = null; + $selectResult = \stream_select($readArray, $writeArray, $exceptArray, 0); + } + // 1 means there is data to read, false means we were unable to check if there is data to read + if (1 === $selectResult || false === $selectResult) { + $result = \fread($this->socket, $length); + } else { + $result = false; + } if ($makeBlockingAfterRead) { \stream_set_blocking($this->socket, true); diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 1e9fcb18..0e7bd904 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -116,7 +116,8 @@ public function testSend(): void $bytes = $instance->sendData('baz', Protocol::TYPE_TEXT); self::assertTrue($bytes >= 3, 'sent text frame'); - + self::assertSame([], $instance->receive(), 'Instantly recieve after send'); + \usleep(500000); // test fix for issue #43 $responses = $instance->receive(); self::assertTrue(\is_array($responses));