From 7299bbb2c54e8e534317867d6764f97b83c4dfa2 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Thu, 28 Nov 2019 09:44:18 +0100 Subject: [PATCH 01/11] Added another test --- .idea/PHPWebSockets.iml | 1 - tests/Helpers/client.php | 7 +++++++ tests/UpdatesWrapperTest.php | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/.idea/PHPWebSockets.iml b/.idea/PHPWebSockets.iml index e71b720..c8ff473 100644 --- a/.idea/PHPWebSockets.iml +++ b/.idea/PHPWebSockets.iml @@ -3,7 +3,6 @@ - diff --git a/tests/Helpers/client.php b/tests/Helpers/client.php index 0c24bf9..59ac365 100755 --- a/tests/Helpers/client.php +++ b/tests/Helpers/client.php @@ -12,6 +12,7 @@ 'message-count' => 0, 'ping-interval' => 0, 'die-at' => 0, + 'close-at' => 0, ]; foreach ($argv as $item) { @@ -28,6 +29,8 @@ $cliArgs['ping-interval'] = (int) substr($item, 16); } elseif (substr($item, 0, 9) === '--die-at=') { $cliArgs['die-at'] = (float) substr($item, 9); + } elseif (substr($item, 0, 11) === '--close-at=') { + $cliArgs['close-at'] = (float) substr($item, 11); } } @@ -48,6 +51,10 @@ die(); } + if ($cliArgs['close-at'] > 0.0 && microtime(TRUE) >= $cliArgs['close-at']) { + $client->close(); + } + foreach ($client->update(0.1) as $update) { // Nothing } diff --git a/tests/UpdatesWrapperTest.php b/tests/UpdatesWrapperTest.php index f701e6b..aa93270 100644 --- a/tests/UpdatesWrapperTest.php +++ b/tests/UpdatesWrapperTest.php @@ -228,7 +228,7 @@ public function testWrapperClientDisappeared() { } - public function testWrapperClientClose() { + public function testWrapperServerClose() { \PHPWebSockets::Log(LogLevel::INFO, 'Starting test..' . PHP_EOL); @@ -244,7 +244,7 @@ public function testWrapperClientClose() { while (microtime(TRUE) <= $runUntil) { - $this->_updatesWrapper->update(0.5, $c = $this->_wsServer->getConnections(TRUE)); + $this->_updatesWrapper->update(0.5, $this->_wsServer->getConnections(TRUE)); if (!$didClose) { $this->assertTrue(proc_get_status($clientProcess)['running'] ?? FALSE); @@ -274,6 +274,34 @@ public function testWrapperClientClose() { } + public function testWrapperClientClose() { + + \PHPWebSockets::Log(LogLevel::INFO, 'Starting test..' . PHP_EOL); + + $this->assertEmpty($this->_wsServer->getConnections(FALSE)); + + $closeAt = microtime(TRUE) + 3.0; + + $descriptorSpec = [['pipe', 'r'], STDOUT, STDERR]; + $clientProcess = proc_open('./tests/Helpers/client.php --address=' . escapeshellarg(self::ADDRESS) . ' --message=' . escapeshellarg('Hello world') . ' --close-at=' . $closeAt . ' --message-count=5', $descriptorSpec, $pipes, realpath(__DIR__ . '/../')); + + while (TRUE) { + + $this->_updatesWrapper->update(0.5, $this->_wsServer->getConnections(TRUE)); + + if (!proc_get_status($clientProcess)['running'] ?? FALSE) { + break; + } + + } + + $this->assertEmpty($this->_wsServer->getConnections(FALSE)); + $this->assertEmpty($this->_connectionList); + + \PHPWebSockets::Log(LogLevel::INFO, 'Test finished' . PHP_EOL); + + } + public function testWrapperClientRefuse() { \PHPWebSockets::Log(LogLevel::INFO, 'Starting test..' . PHP_EOL); @@ -289,7 +317,7 @@ public function testWrapperClientRefuse() { while (microtime(TRUE) <= $runUntil) { - $this->_updatesWrapper->update(0.5, $c = $this->_wsServer->getConnections(TRUE)); + $this->_updatesWrapper->update(0.5, $this->_wsServer->getConnections(TRUE)); if ($clientProcess !== NULL) { @@ -331,7 +359,7 @@ public function testDoubleClose() { while (microtime(TRUE) <= $runUntil) { - $this->_updatesWrapper->update(0.5, $c = $this->_wsServer->getConnections(TRUE)); + $this->_updatesWrapper->update(0.5, $this->_wsServer->getConnections(TRUE)); if (!$didSendDisconnect) { $this->assertTrue(proc_get_status($clientProcess)['running'] ?? FALSE); From 7f47f214c59b2cabb95c29160af3f69a56bce384 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Fri, 27 Dec 2019 17:10:28 +0100 Subject: [PATCH 02/11] Added async client connect support --- .idea/PHPWebSockets.iml | 2 ++ src/PHPWebSockets.php | 1 + src/PHPWebSockets/Client.php | 7 +++++-- tests/Helpers/client.php | 5 ++++- tests/UpdatesWrapperTest.php | 22 ++++++++++++++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/.idea/PHPWebSockets.iml b/.idea/PHPWebSockets.iml index c8ff473..4b484a1 100644 --- a/.idea/PHPWebSockets.iml +++ b/.idea/PHPWebSockets.iml @@ -3,6 +3,8 @@ + + diff --git a/src/PHPWebSockets.php b/src/PHPWebSockets.php index 19c960e..a63653c 100755 --- a/src/PHPWebSockets.php +++ b/src/PHPWebSockets.php @@ -173,6 +173,7 @@ public static function MultiUpdate(array $updateObjects, float $timeout = NULL) } + /** @var \PHPWebSockets\IStreamContainer[] $objectStreamMap */ $objectStreamMap = []; $exceptional = []; $write = []; diff --git a/src/PHPWebSockets/Client.php b/src/PHPWebSockets/Client.php index 497f9ec..985c286 100644 --- a/src/PHPWebSockets/Client.php +++ b/src/PHPWebSockets/Client.php @@ -137,18 +137,21 @@ public function connectToResource($resource, string $path = '/') { * @param string $address * @param string $path * @param array $streamContext + * @param bool $async * * @throws \LogicException * * @return bool */ - public function connect(string $address, string $path = '/', array $streamContext = []) { + public function connect(string $address, string $path = '/', array $streamContext = [], bool $async = FALSE) { if ($this->isOpen()) { throw new \LogicException('The connection is already open!'); } - $this->_stream = @stream_socket_client($address, $this->_streamLastErrorCode, $this->_streamLastError, $this->getConnectTimeout(), STREAM_CLIENT_CONNECT, stream_context_create($streamContext)); + $flags = ($async ? STREAM_CLIENT_ASYNC_CONNECT : STREAM_CLIENT_CONNECT); + + $this->_stream = @stream_socket_client($address, $this->_streamLastErrorCode, $this->_streamLastError, $this->getConnectTimeout(), $flags, stream_context_create($streamContext)); if ($this->_stream === FALSE) { return FALSE; } diff --git a/tests/Helpers/client.php b/tests/Helpers/client.php index 59ac365..76ac986 100755 --- a/tests/Helpers/client.php +++ b/tests/Helpers/client.php @@ -13,6 +13,7 @@ 'ping-interval' => 0, 'die-at' => 0, 'close-at' => 0, + 'async' => FALSE, ]; foreach ($argv as $item) { @@ -31,12 +32,14 @@ $cliArgs['die-at'] = (float) substr($item, 9); } elseif (substr($item, 0, 11) === '--close-at=') { $cliArgs['close-at'] = (float) substr($item, 11); + } elseif ($item === '--async') { + $cliArgs['async'] = TRUE; } } $client = new \PHPWebSockets\Client(); -if (!$client->connect($cliArgs['address'])) { +if (!$client->connect($cliArgs['address'], '/', [], $cliArgs['async'])) { throw new \RuntimeException('Unable to connect to ' . $cliArgs['address']); } diff --git a/tests/UpdatesWrapperTest.php b/tests/UpdatesWrapperTest.php index aa93270..c3cdf67 100644 --- a/tests/UpdatesWrapperTest.php +++ b/tests/UpdatesWrapperTest.php @@ -191,6 +191,28 @@ public function testWrapperNormal() { } + public function testWrapperAsyncClient() { + + \PHPWebSockets::Log(LogLevel::INFO, 'Starting test..' . PHP_EOL); + + $this->assertEmpty($this->_wsServer->getConnections(FALSE)); + + $descriptorSpec = [['pipe', 'r'], STDOUT, STDERR]; + $clientProcess = proc_open('./tests/Helpers/client.php --address=' . escapeshellarg(self::ADDRESS) . ' --message=' . escapeshellarg('Hello world') . ' --message-count=5 --async', $descriptorSpec, $pipes, realpath(__DIR__ . '/../')); + + while (proc_get_status($clientProcess)['running'] ?? FALSE) { + + $this->_updatesWrapper->update(0.5, $this->_wsServer->getConnections(TRUE)); + + } + + $this->assertEmpty($this->_wsServer->getConnections(FALSE)); + $this->assertEmpty($this->_connectionList); + + \PHPWebSockets::Log(LogLevel::INFO, 'Test finished' . PHP_EOL); + + } + public function testWrapperClientDisappeared() { \PHPWebSockets::Log(LogLevel::INFO, 'Starting test..' . PHP_EOL); From 7c72ca3b5289b485ccd3cd60688cfb83b3153a41 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Fri, 27 Dec 2019 17:51:42 +0100 Subject: [PATCH 03/11] Added async client connect refuse support --- .travis.yml | 3 +-- src/PHPWebSockets/Client.php | 16 ++++++++++- src/PHPWebSockets/Server.php | 6 ++--- src/PHPWebSockets/Update/Error.php | 4 ++- src/PHPWebSockets/UpdatesWrapper.php | 3 +++ tests/UpdatesWrapperTest.php | 40 ++++++++++++++++++++++++++++ 6 files changed, 65 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 15423c6..8c9a969 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ php: - 7.1 - 7.2 - 7.3 - - 7.4snapshot + - 7.4 - nightly env: @@ -22,7 +22,6 @@ env: matrix: fast_finish: true allow_failures: - - php: 7.4snapshot - php: nightly before_script: diff --git a/src/PHPWebSockets/Client.php b/src/PHPWebSockets/Client.php index 985c286..9324297 100644 --- a/src/PHPWebSockets/Client.php +++ b/src/PHPWebSockets/Client.php @@ -49,6 +49,13 @@ class Client extends AConnection { */ protected $_handshakeAccepted = FALSE; + /** + * If we are currently trying to connect async + * + * @var bool + */ + protected $_isConnectingAsync = FALSE; + /** * The last error received from the stream * @@ -115,7 +122,7 @@ public function __construct(LoggerInterface $logger = NULL) { public function connectToResource($resource, string $path = '/') { if (!is_resource($resource)) { - throw new \InvalidArgumentException('Argument is not a resource!'); + throw new \InvalidArgumentException('Argument 1 is not a resource!'); } if ($this->isOpen()) { @@ -149,6 +156,8 @@ public function connect(string $address, string $path = '/', array $streamContex throw new \LogicException('The connection is already open!'); } + $this->_isConnectingAsync = $async; + $flags = ($async ? STREAM_CLIENT_ASYNC_CONNECT : STREAM_CLIENT_CONNECT); $this->_stream = @stream_socket_client($address, $this->_streamLastErrorCode, $this->_streamLastError, $this->getConnectTimeout(), $flags, stream_context_create($streamContext)); @@ -243,6 +252,8 @@ public function handleRead() : \Generator { if ($this->_remoteSentDisconnect && $this->_weSentDisconnect) { yield new Update\Read(Update\Read::C_SOCK_DISCONNECT, $this); + } elseif ($this->_isConnectingAsync) { + yield new Update\Error(Update\Error::C_ASYNC_CONNECT_FAILED, $this); } else { yield new Update\Error(Update\Error::C_READ_UNEXPECTED_DISCONNECT, $this); } @@ -253,6 +264,9 @@ public function handleRead() : \Generator { } else { + // If we've received data we can be sure we're connected + $this->_isConnectingAsync = FALSE; + $handshakeAccepted = $this->handshakeAccepted(); if (!$handshakeAccepted) { diff --git a/src/PHPWebSockets/Server.php b/src/PHPWebSockets/Server.php index 8b939a1..0842cf5 100644 --- a/src/PHPWebSockets/Server.php +++ b/src/PHPWebSockets/Server.php @@ -246,14 +246,14 @@ public function update(float $timeout = NULL) : \Generator { } /** - * Gets called by the accepting web socket to notify the server that a new connection attempt has occured + * Gets called by the accepting web socket to notify the server that a new connection attempt has occurred * * @return \Generator|\PHPWebSockets\AUpdate[] */ public function gotNewConnection() : \Generator { if (!$this->_autoAccept) { - yield new Update\Read(Update\Read::C_NEW_SOCKET_CONNECTION_AVAILABLE, $this->_acceptingConnection); + yield new Update\Read(Update\Read::C_NEW_SOCKET_CONNECTION_AVAILABLE, NULL); } else { yield from $this->acceptNewConnection(); } @@ -307,7 +307,7 @@ public function getErrorPageForCode(int $errorCode, string $fallbackErrorString '%serverIdentifier%' => $this->getServerIdentifier(), ]; - return str_replace(array_keys($replaceFields), array_values($replaceFields), "HTTP/1.1 %errorCode% %errorString%\r\nServer: %serverIdentifier%\r\n\r\n%errorCode% %errorString%

%errorCode% %errorString%


%serverIdentifier%
\r\n\r\n"); + return str_replace(array_keys($replaceFields), array_values($replaceFields), "HTTP/1.1 %errorCode% %errorString%\r\nServer: %serverIdentifier%\r\n\r\n%errorCode% %errorString%

%errorCode% %errorString%


%serverIdentifier%
\r\n\r\n"); } /** diff --git a/src/PHPWebSockets/Update/Error.php b/src/PHPWebSockets/Update/Error.php index d43ad89..9dd1e26 100644 --- a/src/PHPWebSockets/Update/Error.php +++ b/src/PHPWebSockets/Update/Error.php @@ -51,7 +51,8 @@ class Error extends AUpdate { C_WRITE_INVALID_TARGET_STREAM = 14, C_READ_DISCONNECT_DURING_HANDSHAKE = 15, C_DISCONNECT_TIMEOUT = 16, - C_READ_NO_STREAM_FOR_NEW_MESSAGE = 17; + C_READ_NO_STREAM_FOR_NEW_MESSAGE = 17, + C_ASYNC_CONNECT_FAILED = 18; /** * @deprecated Constant has the wrong name, use C_WRITE_INVALID_TARGET_STREAM instead @@ -85,6 +86,7 @@ public static function StringForCode(int $code) : string { self::C_READ_DISCONNECT_DURING_HANDSHAKE => 'Disconnect during handshake', self::C_DISCONNECT_TIMEOUT => 'The remote failed to respond in time to our disconnect', self::C_READ_NO_STREAM_FOR_NEW_MESSAGE => 'No stream was returned by the newMessageStreamCallback', + self::C_ASYNC_CONNECT_FAILED => 'Async connect failed', ]; return $codes[$code] ?? 'Unknown error code ' . $code; diff --git a/src/PHPWebSockets/UpdatesWrapper.php b/src/PHPWebSockets/UpdatesWrapper.php index 9f8b210..c5c0de2 100644 --- a/src/PHPWebSockets/UpdatesWrapper.php +++ b/src/PHPWebSockets/UpdatesWrapper.php @@ -254,6 +254,9 @@ public function update(float $timeout = NULL, array $tempStreams = []) { case Update\Error::C_READ_DISCONNECT_DURING_HANDSHAKE: // $this->_onDisconnectDuringHandshake($update); break; + case Update\Error::C_ASYNC_CONNECT_FAILED: + $this->_onDisconnect($update); + break; default: throw new \UnexpectedValueException('Unknown or unsupported update code for error: ' . $code); } diff --git a/tests/UpdatesWrapperTest.php b/tests/UpdatesWrapperTest.php index c3cdf67..3a6a050 100644 --- a/tests/UpdatesWrapperTest.php +++ b/tests/UpdatesWrapperTest.php @@ -364,6 +364,46 @@ public function testWrapperClientRefuse() { } + public function testWrapperAsyncClientTCPRefuse() { + + \PHPWebSockets::Log(LogLevel::INFO, 'Starting test..' . PHP_EOL); + + $this->assertEmpty($this->_wsServer->getConnections(FALSE)); + + $this->_refuseNextConnection = TRUE; + + $runUntil = microtime(TRUE) + 8.0; + + $descriptorSpec = [['pipe', 'r'], STDOUT, STDERR]; + $clientProcess = proc_open('./tests/Helpers/client.php --address=' . escapeshellarg('tcp://127.0.0.1:9000') . ' --message=' . escapeshellarg('Hello world') . ' --message-count=1 --async', $descriptorSpec, $pipes, realpath(__DIR__ . '/../')); + + while (microtime(TRUE) <= $runUntil) { + + $this->_updatesWrapper->update(0.5, $this->_wsServer->getConnections(TRUE)); + + if ($clientProcess !== NULL) { + + $status = proc_get_status($clientProcess); + if (!$status['running']) { + + \PHPWebSockets::Log(LogLevel::INFO, 'Client disappeared'); + $clientProcess = NULL; + + } + + } + + } + + $this->assertEmpty($this->_wsServer->getConnections(FALSE)); + $this->assertEmpty($this->_connectionList); + + $this->_refuseNextConnection = FALSE; + + \PHPWebSockets::Log(LogLevel::INFO, 'Test finished' . PHP_EOL); + + } + public function testDoubleClose() { \PHPWebSockets::Log(LogLevel::INFO, 'Starting test..' . PHP_EOL); From e3df4d124413d383d8326579ae24a633a0b16408 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 30 Dec 2019 14:50:40 +0100 Subject: [PATCH 04/11] Bumped VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 437459c..e70b452 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5.0 +2.6.0 From 8cf51d30ec0a49cd0e08d5aefbb579da3047c6cd Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 30 Dec 2019 16:17:58 +0100 Subject: [PATCH 05/11] Fixed throw tags --- src/PHPWebSockets/AConnection.php | 2 +- src/PHPWebSockets/Client.php | 2 -- src/PHPWebSockets/Framer.php | 6 ++---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/PHPWebSockets/AConnection.php b/src/PHPWebSockets/AConnection.php index 5e64d8e..f3be896 100644 --- a/src/PHPWebSockets/AConnection.php +++ b/src/PHPWebSockets/AConnection.php @@ -732,7 +732,7 @@ public function writeRaw(string $data, bool $priority) { * @param int $opcode * @param bool $isFinal * - * @throws \Exception + * @return void */ public function write(string $data, int $opcode = \PHPWebSockets::OPCODE_FRAME_TEXT, bool $isFinal = TRUE) { $this->writeRaw(Framer::Frame($data, $this->_shouldMask(), $opcode, $isFinal), \PHPWebSockets::IsPriorityOpcode($opcode)); diff --git a/src/PHPWebSockets/Client.php b/src/PHPWebSockets/Client.php index 9324297..80e66d4 100644 --- a/src/PHPWebSockets/Client.php +++ b/src/PHPWebSockets/Client.php @@ -219,8 +219,6 @@ public function getLastError() { * * @param float|null $timeout The amount of seconds to wait for updates, setting this value to NULL causes this function to block indefinitely until there is an update * - * @throws \Exception - * * @return \Generator|\PHPWebSockets\AUpdate[] */ public function update(float $timeout = NULL) : \Generator { diff --git a/src/PHPWebSockets/Framer.php b/src/PHPWebSockets/Framer.php index 159dba9..4ee85d7 100644 --- a/src/PHPWebSockets/Framer.php +++ b/src/PHPWebSockets/Framer.php @@ -174,17 +174,15 @@ public static function GetFramePayload(string $frame, array $headers = NULL) { } /** - * Frames a message - * * @param string $data * @param bool $mask * @param int $opcode * @param bool $isFinal * @param int $rsv * - * @throws \Exception - * * @return string + * @throws \RangeException + * @throws \LogicException */ public static function Frame(string $data, bool $mask, int $opcode = \PHPWebSockets::OPCODE_FRAME_TEXT, bool $isFinal = TRUE, int $rsv = 0) : string { From 5bb06cd6ef85dbb9348fa2469626517a1abc6f47 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 30 Dec 2019 16:26:37 +0100 Subject: [PATCH 06/11] More doc fixes --- src/PHPWebSockets/AConnection.php | 12 ++++++++---- src/PHPWebSockets/Client.php | 2 -- src/PHPWebSockets/Server.php | 24 ++++++++++++++++++------ src/PHPWebSockets/Server/Connection.php | 2 -- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/PHPWebSockets/AConnection.php b/src/PHPWebSockets/AConnection.php index f3be896..26ca055 100644 --- a/src/PHPWebSockets/AConnection.php +++ b/src/PHPWebSockets/AConnection.php @@ -210,6 +210,8 @@ abstract class AConnection implements IStreamContainer, LoggerAwareInterface { * Sets the maximum size for the handshake in bytes * * @param int $maxLength + * + * @return void */ public function setMaxHandshakeLength(int $maxLength) { $this->_maxHandshakeLength = $maxLength; @@ -263,6 +265,8 @@ public function writeUntilEmpty(float $timeout = NULL) : bool { /** * Sets that we should close the connection after all our writes have finished + * + * @return void */ public function setCloseAfterWrite() { $this->_closeAfterWrite = TRUE; @@ -290,8 +294,6 @@ protected function _afterOpen() { * * @param string $newData * - * @throws \Exception - * * @return \Generator|\PHPWebSockets\AUpdate[] */ protected function _handlePacket(string $newData) : \Generator { @@ -666,7 +668,7 @@ protected function _afterReportClose() { * @param int $opcode * @param int $frameSize * - * @throws \Exception + * @return void */ public function writeMultiFramed(string $data, int $opcode = \PHPWebSockets::OPCODE_FRAME_TEXT, int $frameSize = 65535) { @@ -766,7 +768,7 @@ public function waitUntilDisconnect(float $timeout = NULL) : bool { * @param string $reason * @param float $timeout * - * @throws \Exception + * @return void */ public function sendDisconnect(int $code, string $reason = '', float $timeout = 10.0) { @@ -809,6 +811,8 @@ protected function _checkRSVBits(array $headers) : bool { * If TRUE is returned from the callback a memory buffer will be used instead * * @param callable|null $callable + * + * @return void */ public function setNewMessageStreamCallback(callable $callable = NULL) { $this->_newMessageStreamCallback = $callable; diff --git a/src/PHPWebSockets/Client.php b/src/PHPWebSockets/Client.php index 80e66d4..b929b87 100644 --- a/src/PHPWebSockets/Client.php +++ b/src/PHPWebSockets/Client.php @@ -226,8 +226,6 @@ public function update(float $timeout = NULL) : \Generator { } /** - * @throws \Exception - * * @return \Generator|\PHPWebSockets\AUpdate[] */ public function handleRead() : \Generator { diff --git a/src/PHPWebSockets/Server.php b/src/PHPWebSockets/Server.php index 0842cf5..375fd40 100644 --- a/src/PHPWebSockets/Server.php +++ b/src/PHPWebSockets/Server.php @@ -144,7 +144,7 @@ class Server implements LoggerAwareInterface { * @param bool $useCrypto If we should enable crypto on newly accepted connections * @param \Psr\Log\LoggerInterface|null $logger * - * @throws \RuntimeException + * @return void */ public function __construct(string $address = NULL, array $streamContext = [], bool $useCrypto = FALSE, LoggerInterface $logger = NULL) { @@ -237,8 +237,6 @@ public function createServerClientPair() : array { * * @param float|null $timeout The amount of seconds to wait for updates, setting this value to NULL causes this function to block indefinitely until there is an update * - * @throws \Exception - * * @return \Generator|\PHPWebSockets\AUpdate[] */ public function update(float $timeout = NULL) : \Generator { @@ -343,6 +341,8 @@ public function getServerIdentifier() : string { * Sets the server identifier string reported to clients * * @param string|null $identifier + * + * @return void */ public function setServerIdentifier(string $identifier = NULL) { $this->_serverIdentifier = $identifier; @@ -373,7 +373,7 @@ public function getAcceptingConnection() { * * @param bool $includeAccepting * - * @return array|\PHPWebSockets\Server\Connection[] + * @return \PHPWebSockets\Server\Connection[] */ public function getConnections(bool $includeAccepting = FALSE) : array { @@ -396,7 +396,7 @@ public function getConnections(bool $includeAccepting = FALSE) : array { * @param int $closeCode * @param string $reason * - * @throws \Exception + * @return void */ public function disconnectAll(int $closeCode, string $reason = '') { @@ -419,6 +419,8 @@ public function getAddress() : string { * This should be called after a process has been fork with the PID returned from pcntl_fork, this ensures that the connection is closed in the new fork without interupting the main process * * @param int $pid + * + * @return void */ public function processDidFork(int $pid) { @@ -441,7 +443,7 @@ public function processDidFork(int $pid) { * @param \PHPWebSockets\Server\Connection $connection * @param bool $closeConnection * - * @throws \LogicException + * @return void */ public function removeConnection(Server\Connection $connection, bool $closeConnection = TRUE) { @@ -481,6 +483,8 @@ public function getTrustForwardedHeaders() : bool { * Sets the time in seconds in which the stream_socket_accept method has to accept the connection or fail * * @param float $timeout + * + * @return void */ public function setSocketAcceptTimeout(float $timeout) { $this->_socketAcceptTimeout = $timeout; @@ -499,6 +503,8 @@ public function getSocketAcceptTimeout() : float { * Sets if we should disable the cleanup which happens after forking * * @param bool $disableForkCleanup + * + * @return void */ public function setDisableForkCleanup(bool $disableForkCleanup) { $this->_disableForkCleanup = $disableForkCleanup; @@ -517,6 +523,8 @@ public function getDisableForkCleanup() : bool { * Sets if we should automatically accept the connection * * @param bool $autoAccept + * + * @return void */ public function setAutoAccept(bool $autoAccept) { $this->_autoAccept = $autoAccept; @@ -526,6 +534,8 @@ public function setAutoAccept(bool $autoAccept) { * Sets the class that will be our connection, this has to be an extension of \PHPWebSockets\Server\Connection * * @param string $class + * + * @return void */ public function setConnectionClass(string $class) { @@ -557,6 +567,8 @@ public function usesCrypto() : bool { /** * Closes the webserver, note: clients should be notified beforehand that we are disconnecting, calling close while having connected clients will result in an improper disconnect + * + * @return void */ public function close() { diff --git a/src/PHPWebSockets/Server/Connection.php b/src/PHPWebSockets/Server/Connection.php index e623381..5b22d03 100644 --- a/src/PHPWebSockets/Server/Connection.php +++ b/src/PHPWebSockets/Server/Connection.php @@ -113,8 +113,6 @@ public function __construct(Server $server, $stream, string $streamName, int $in /** * Attempts to read from our connection * - * @throws \Exception - * * @return \Generator|\PHPWebSockets\AUpdate[] */ public function handleRead() : \Generator { From 28de39b47fd616280aa185a80cac026959ac23e4 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 30 Dec 2019 16:27:37 +0100 Subject: [PATCH 07/11] Fix --- src/PHPWebSockets/Framer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PHPWebSockets/Framer.php b/src/PHPWebSockets/Framer.php index 4ee85d7..535b04d 100644 --- a/src/PHPWebSockets/Framer.php +++ b/src/PHPWebSockets/Framer.php @@ -180,9 +180,10 @@ public static function GetFramePayload(string $frame, array $headers = NULL) { * @param bool $isFinal * @param int $rsv * - * @return string * @throws \RangeException * @throws \LogicException + * + * @return string */ public static function Frame(string $data, bool $mask, int $opcode = \PHPWebSockets::OPCODE_FRAME_TEXT, bool $isFinal = TRUE, int $rsv = 0) : string { From eaf10c531f91b48714a25a10739d8b64efaf7098 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Mon, 30 Dec 2019 16:35:26 +0100 Subject: [PATCH 08/11] Style fixes --- .idea/php-test-framework.xml | 14 ++++++++++++++ src/PHPWebSockets/Framer.php | 3 --- src/PHPWebSockets/UpdatesWrapper.php | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .idea/php-test-framework.xml diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml new file mode 100644 index 0000000..b70695f --- /dev/null +++ b/.idea/php-test-framework.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/PHPWebSockets/Framer.php b/src/PHPWebSockets/Framer.php index 535b04d..305d80a 100644 --- a/src/PHPWebSockets/Framer.php +++ b/src/PHPWebSockets/Framer.php @@ -180,9 +180,6 @@ public static function GetFramePayload(string $frame, array $headers = NULL) { * @param bool $isFinal * @param int $rsv * - * @throws \RangeException - * @throws \LogicException - * * @return string */ public static function Frame(string $data, bool $mask, int $opcode = \PHPWebSockets::OPCODE_FRAME_TEXT, bool $isFinal = TRUE, int $rsv = 0) : string { diff --git a/src/PHPWebSockets/UpdatesWrapper.php b/src/PHPWebSockets/UpdatesWrapper.php index c5c0de2..73e54cc 100644 --- a/src/PHPWebSockets/UpdatesWrapper.php +++ b/src/PHPWebSockets/UpdatesWrapper.php @@ -210,7 +210,7 @@ public function update(float $timeout = NULL, array $tempStreams = []) { $code = $update->getCode(); switch ($code) { case Update\Error::C_SELECT: - $this->_onSelectInterupt($update); + $this->_onSelectInterrupt($update); break; case Update\Error::C_READ: $this->_onReadFail($update); @@ -476,7 +476,7 @@ private function _onSocketConnectionAvailable(Update\Read $update) { * Error events */ - private function _onSelectInterupt(Update\Error $update) { + private function _onSelectInterrupt(Update\Error $update) { // Nothing } From 8d49de0bb60538c1e62db053d63d1992d8ada796 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Tue, 31 Dec 2019 09:47:38 +0100 Subject: [PATCH 09/11] Alot of cleanup --- src/PHPWebSockets.php | 2 -- src/PHPWebSockets/AConnection.php | 2 ++ src/PHPWebSockets/AUpdate.php | 6 +++--- src/PHPWebSockets/BasicLogger.php | 2 ++ src/PHPWebSockets/Client.php | 9 +++------ src/PHPWebSockets/Server.php | 5 +---- src/PHPWebSockets/Server/Connection.php | 10 +++++++--- src/PHPWebSockets/TLogAware.php | 2 ++ 8 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/PHPWebSockets.php b/src/PHPWebSockets.php index a63653c..7a8173d 100755 --- a/src/PHPWebSockets.php +++ b/src/PHPWebSockets.php @@ -157,8 +157,6 @@ final class PHPWebSockets { * @param \PHPWebSockets\IStreamContainer[] $updateObjects * @param float|null $timeout The amount of seconds to wait for updates, setting this value to NULL causes this function to block indefinitely until there is an update * - * @throws \InvalidArgumentException - * * @return \Generator|\PHPWebSockets\AUpdate[] */ public static function MultiUpdate(array $updateObjects, float $timeout = NULL) : \Generator { diff --git a/src/PHPWebSockets/AConnection.php b/src/PHPWebSockets/AConnection.php index 26ca055..1d4ade7 100644 --- a/src/PHPWebSockets/AConnection.php +++ b/src/PHPWebSockets/AConnection.php @@ -856,6 +856,8 @@ public function getOpenedTimestamp() { * Sets the maximum amount of bytes to write per cycle * * @param int $rate + * + * @return void */ public function setWriteRate(int $rate) { $this->_writeRate = $rate; diff --git a/src/PHPWebSockets/AUpdate.php b/src/PHPWebSockets/AUpdate.php index 8f8127d..94f849f 100644 --- a/src/PHPWebSockets/AUpdate.php +++ b/src/PHPWebSockets/AUpdate.php @@ -35,7 +35,7 @@ abstract class AUpdate { /** * The source object related to this update * - * @var object|null + * @var \PHPWebSockets\AConnection|null */ protected $_sourceConnection = NULL; @@ -51,9 +51,9 @@ abstract class AUpdate { */ protected $_code = 0; - public function __construct(int $code, AConnection $sourceObject = NULL) { + public function __construct(int $code, AConnection $sourceConnection = NULL) { - $this->_sourceConnection = $sourceObject; + $this->_sourceConnection = $sourceConnection; $this->_code = $code; if (\PHPWebSockets::ShouldUpdateTrace($this)) { diff --git a/src/PHPWebSockets/BasicLogger.php b/src/PHPWebSockets/BasicLogger.php index eed9f78..a0f1daa 100644 --- a/src/PHPWebSockets/BasicLogger.php +++ b/src/PHPWebSockets/BasicLogger.php @@ -62,6 +62,8 @@ public function log($level, $message, array $context = []) { * Enables or disables debug logging * * @param bool $debug + * + * @return void */ public function setDebugMode(bool $debug) { $this->_debug = $debug; diff --git a/src/PHPWebSockets/Client.php b/src/PHPWebSockets/Client.php index b929b87..a1b7f58 100644 --- a/src/PHPWebSockets/Client.php +++ b/src/PHPWebSockets/Client.php @@ -114,12 +114,9 @@ public function __construct(LoggerInterface $logger = NULL) { * @param resource $resource * @param string $path * - * @throws \InvalidArgumentException - * @throws \LogicException - * * @return bool */ - public function connectToResource($resource, string $path = '/') { + public function connectToResource($resource, string $path = '/') : bool { if (!is_resource($resource)) { throw new \InvalidArgumentException('Argument 1 is not a resource!'); @@ -146,8 +143,6 @@ public function connectToResource($resource, string $path = '/') { * @param array $streamContext * @param bool $async * - * @throws \LogicException - * * @return bool */ public function connect(string $address, string $path = '/', array $streamContext = [], bool $async = FALSE) { @@ -362,6 +357,8 @@ public function getUserAgent() : string { * @see https://tools.ietf.org/html/rfc6455#section-5.3 * * @param bool $mask + * + * @return void */ public function setMasksPayload(bool $mask) { $this->_shouldMask = $mask; diff --git a/src/PHPWebSockets/Server.php b/src/PHPWebSockets/Server.php index 375fd40..87fa793 100644 --- a/src/PHPWebSockets/Server.php +++ b/src/PHPWebSockets/Server.php @@ -261,9 +261,6 @@ public function gotNewConnection() : \Generator { /** * Accepts a new connection from the accepting socket * - * @throws \LogicException - * @throws \RuntimeException - * * @return \Generator|\PHPWebSockets\AUpdate[] */ public function acceptNewConnection() : \Generator { @@ -313,7 +310,7 @@ public function getErrorPageForCode(int $errorCode, string $fallbackErrorString * * @param resource $stream * - * @return Server\Connection|null + * @return \PHPWebSockets\Server\Connection|null */ public function getConnectionByStream($stream) { diff --git a/src/PHPWebSockets/Server/Connection.php b/src/PHPWebSockets/Server/Connection.php index 5b22d03..e2a4c80 100644 --- a/src/PHPWebSockets/Server/Connection.php +++ b/src/PHPWebSockets/Server/Connection.php @@ -303,9 +303,9 @@ protected function _parseHeaders() { /** * Accepts the connection * - * @param string|null $protocol The accepted protocol + * @param string|NULL $protocol The accepted protocol * - * @throws \LogicException + * @return void */ public function accept(string $protocol = NULL) { @@ -329,7 +329,7 @@ public function accept(string $protocol = NULL) { * * @param int $errCode * - * @throws \LogicException + * @return void */ public function deny(int $errCode) { @@ -344,6 +344,8 @@ public function deny(int $errCode) { /** * Detaches this connection from its server + * + * @return void */ public function detach() { @@ -360,6 +362,8 @@ public function detach() { * Sets the time in seconds in which the client has to send its handshake * * @param float $timeout + * + * @return void */ public function setAcceptTimeout(float $timeout) { $this->_acceptTimeout = $timeout; diff --git a/src/PHPWebSockets/TLogAware.php b/src/PHPWebSockets/TLogAware.php index d427a32..6188ce4 100644 --- a/src/PHPWebSockets/TLogAware.php +++ b/src/PHPWebSockets/TLogAware.php @@ -70,6 +70,8 @@ public function getLogger() { * @param string $level * @param string $message * @param array $context + * + * @return void */ protected function _log(string $level, string $message, array $context = []) { From 162abf5e45d0433c439a3ee13df95f61b9b4790c Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Tue, 31 Dec 2019 10:08:37 +0100 Subject: [PATCH 10/11] Fixes --- src/PHPWebSockets.php | 5 ++++- src/PHPWebSockets/Server/Connection.php | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/PHPWebSockets.php b/src/PHPWebSockets.php index 7a8173d..9a4b6da 100755 --- a/src/PHPWebSockets.php +++ b/src/PHPWebSockets.php @@ -173,14 +173,17 @@ public static function MultiUpdate(array $updateObjects, float $timeout = NULL) /** @var \PHPWebSockets\IStreamContainer[] $objectStreamMap */ $objectStreamMap = []; + /** @var resource[] $exceptional */ $exceptional = []; + /** @var resource[] $write */ $write = []; + /** @var resource[] $read */ $read = []; foreach ($updateObjects as $object) { if (!$object instanceof \PHPWebSockets\IStreamContainer) { - throw new \InvalidArgumentException('Got invalid object, all provided objects should implement of \PHPWebSockets\IStreamContainer'); + throw new \InvalidArgumentException('Got invalid object, all provided objects should implement ' . \PHPWebSockets\IStreamContainer::class); } yield from $object->beforeStreamSelect(); diff --git a/src/PHPWebSockets/Server/Connection.php b/src/PHPWebSockets/Server/Connection.php index e2a4c80..f8eb150 100644 --- a/src/PHPWebSockets/Server/Connection.php +++ b/src/PHPWebSockets/Server/Connection.php @@ -303,7 +303,7 @@ protected function _parseHeaders() { /** * Accepts the connection * - * @param string|NULL $protocol The accepted protocol + * @param string|null $protocol The accepted protocol * * @return void */ From 43aa66fd8396c245c046e029cd6bd440277123c9 Mon Sep 17 00:00:00 2001 From: Kevin Meijer Date: Tue, 31 Dec 2019 10:13:59 +0100 Subject: [PATCH 11/11] Restored comment --- src/PHPWebSockets/Framer.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/PHPWebSockets/Framer.php b/src/PHPWebSockets/Framer.php index 305d80a..d099bfb 100644 --- a/src/PHPWebSockets/Framer.php +++ b/src/PHPWebSockets/Framer.php @@ -174,6 +174,8 @@ public static function GetFramePayload(string $frame, array $headers = NULL) { } /** + * Frames a message + * * @param string $data * @param bool $mask * @param int $opcode