From 3cc7947f3bad86bf313373518a93b1d17cbeefac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 2 Apr 2022 22:40:00 +0200 Subject: [PATCH] Fix strict types for `socket_select()` without timeout on PHP 8+ --- src/Socket.php | 4 ++-- tests/SocketTest.php | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/Socket.php b/src/Socket.php index 4b64fec..42a4570 100644 --- a/src/Socket.php +++ b/src/Socket.php @@ -313,7 +313,7 @@ public function recvFrom($length, $flags, &$remote) */ public function selectRead($sec = 0) { - $usec = $sec === null ? null : (int) (($sec - floor($sec)) * 1000000); + $usec = $sec === null ? 0 : (int) (($sec - floor($sec)) * 1000000); $r = array($this->resource); $n = null; $ret = @socket_select($r, $n, $n, $sec === null ? null : (int) $sec, $usec); @@ -334,7 +334,7 @@ public function selectRead($sec = 0) */ public function selectWrite($sec = 0) { - $usec = $sec === null ? null : (int) (($sec - floor($sec)) * 1000000); + $usec = $sec === null ? 0 : (int) (($sec - floor($sec)) * 1000000); $w = array($this->resource); $n = null; $ret = @socket_select($n, $w, $n, $sec === null ? null : (int) $sec, $usec); diff --git a/tests/SocketTest.php b/tests/SocketTest.php index d9c7bc9..4460889 100644 --- a/tests/SocketTest.php +++ b/tests/SocketTest.php @@ -260,6 +260,42 @@ public function testServerNonBlockingAcceptClient(Socket $server) $peer->close(); } + /** + * @depends testServerNonBlockingAcceptClient + */ + public function testServerAcceptsClientWithoutTimeout() + { + $server = $this->factory->createListen(0); + + // create local client connected to the given server + $client = $this->factory->createClient($server->getSockName()); + + // client connected, so we should be able to accept() this socket immediately + $now = microtime(true); + $server->selectRead(null); + $peer = $server->accept(); + $this->assertLessThan(1.0, microtime(true) - $now); + + // peer should be writable right away + $now = microtime(true); + $this->assertTrue($peer->selectWrite(null)); + $peer->write('test'); + $this->assertLessThan(1.0, microtime(true) - $now); + + // expect to receive the message in one chunk + $this->assertEquals('test', $client->read(100)); + + // disconnect local client + $client->close(); + + // disconnection should be detected withing 1s max + $now = microtime(true); + $this->assertTrue($peer->selectRead(null)); + $this->assertLessThan(1.0, microtime(true) - $now); + + $peer->close(); + } + public function testBindThrowsWhenSocketIsAlreadyClosed() { $socket = $this->factory->createTcp4();