From: Roland Häder Date: Sat, 20 May 2017 20:23:24 +0000 (+0200) Subject: Continued rewriting: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=7cf0a7a80247f679f274ef3703925bed6d68a26e;p=hub.git Continued rewriting: - handleSocketError() and all it's brothers and sisters (means call-back methods) are now residing in SocketContainer - still more rewrites for existing old parts - renamed factory method to createListenFileSocket() as this creates a listening file socket (mostly for IPC) Signed-off-by: Roland Häder --- diff --git a/application/hub/classes/class_BaseHubSystem.php b/application/hub/classes/class_BaseHubSystem.php index 1f100e258..2ffff9cd0 100644 --- a/application/hub/classes/class_BaseHubSystem.php +++ b/application/hub/classes/class_BaseHubSystem.php @@ -3,7 +3,6 @@ namespace Hub\Generic; // Import application-specific stuff -use Hub\Container\Socket\StorableSocket; use Hub\Handler\Protocol\HandleableProtocol; use Hub\Handler\RawData\BaseRawDataHandler; use Hub\Information\ShareableInfo; @@ -16,7 +15,6 @@ use Hub\Pool\Poolable; use CoreFramework\Listener\Listenable; use CoreFramework\Object\BaseFrameworkSystem; use CoreFramework\Socket\InvalidSocketException; -use CoreFramework\Socket\NoSocketErrorDetectedException; /** * A general hub system class @@ -138,55 +136,6 @@ class BaseHubSystem extends BaseFrameworkSystem implements HubInterface { return $isset; } - /** - * Handles socket error for given socket resource and peer data. This method - * validates socket resource stored in given container if it is a valid - * resource (see is_resource()) but assumes valid data in array - * $recipientData, except that count($recipientData) is always 2. - * - * @param $method Value of __METHOD__ from calling method - * @param $line Value of __LINE__ from calling method - * @param $socketInstance An instance of a StoreableSocket class - * @param $socketData A valid socket data array (0 = IP/file name, 1 = port) - * @return void - * @throws InvalidSocketException If the stored socket resource is no socket resource - * @throws NoSocketErrorDetectedException If socket_last_error() gives zero back - * @todo Move all this socket-related stuff into own class, most of it resides in BaseListener - */ - public final function handleSocketError ($method, $line, StorableSocket $socketInstance, array $socketData) { - // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('HUB-SYSTEM: Handling socket errorCode=%d - CALLED!', $socketInstance->getLastSocketError())); - - // This method handles only socket resources - if (!$socketInstance->isValidSocket()) { - // No resource, abort here - throw new InvalidSocketException(array($this, $socketInstance->getSocketResource()), BaseListener::EXCEPTION_INVALID_SOCKET); - } // END - if - - // Check socket array, 1st element is mostly IP address (or file name), 2nd is port number - //* DEBUG-DIE: */ die(__METHOD__ . ':socketData=' . print_r($socketData, true)); - assert(isset($socketData[0])); - assert(isset($socketData[1])); - - // Get error code for first validation (0 is not an error) - $errorCode = $socketInstance->getLastSocketError(); - - // If the error code is zero, someone called this method without an error - if ($errorCode == 0) { - // No error detected (or previously cleared outside this method) - throw new NoSocketErrorDetectedException(array($this, $socketInstance->getSocketResource()), BaseListener::EXCEPTION_NO_SOCKET_ERROR); - } // END - if - - // Get handler (method) name - $handlerName = $this->getSocketErrorHandlerFromCode($errorCode); - - // Call-back the error handler method - call_user_func_array(array($this, $handlerName), array($socketInstance, $socketData)); - - // Finally clear the error because it has been handled - $socketInstance->clearLastSocketError(); - } - /** * Setter for network package handler instance * diff --git a/application/hub/classes/container/socket/class_SocketContainer.php b/application/hub/classes/container/socket/class_SocketContainer.php index b23195fcd..c62462bec 100644 --- a/application/hub/classes/container/socket/class_SocketContainer.php +++ b/application/hub/classes/container/socket/class_SocketContainer.php @@ -12,6 +12,7 @@ use CoreFramework\Container\BaseContainer; use CoreFramework\Listener\Listenable; use CoreFramework\Registry\Registerable; use CoreFramework\Socket\InvalidSocketException; +use CoreFramework\Socket\NoSocketErrorDetectedException; use CoreFramework\Visitor\Visitable; use CoreFramework\Visitor\Visitor; @@ -246,6 +247,7 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable * Getter for last socket error * * @return $lastSocketError Last socket error + * @throws InvalidSocketException If socket is invalid */ public function getLastSocketError () { // Should be valid socket @@ -267,10 +269,91 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable /** * Tries to bind the socket. * + * @param $bindAddress Where to bind the socket to (e.g. Uni* socket file) + * @param $bindPort Optional port to bind to * @return $result Result from binding socket + * @throws InvalidSocketException If socket is invalid */ - public function bindSocketTo () { - $this->partialStub('Unfinished method.'); + public function bindSocketTo ($bindAddress, $bindPort = 0) { + // Should be valid socket + if (!$this->isValidSocket()) { + // Throw exception + throw new InvalidSocketException(array($this, $this->getSocketResource()), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Try to bind it to + $result = socket_bind($this->getSocketResource(), $bindAddress, $bindPort); + + // Return result + return $result; + } + + /** + * Tries to listen on the socket + * + * @return $result Result from listening on socket + * @throws InvalidSocketException If socket is valid + */ + public function listenOnSocket () { + // Should be valid socket + if (!$this->isValidSocket()) { + // Throw exception + throw new InvalidSocketException(array($this, $this->getSocketResource()), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Try to listen on socket + $result = socket_listen($this->getSocketResource()); + + // Return result + return $result; + } + + /** + * Handles socket error for given socket resource and peer data. This method + * validates socket resource stored in given container if it is a valid + * resource (see is_resource()) but assumes valid data in array + * $recipientData, except that count($recipientData) is always 2. + * + * @param $method Value of __METHOD__ from calling method + * @param $line Value of __LINE__ from calling method + * @param $socketData A valid socket data array (0 = IP/file name, 1 = port) + * @return void + * @throws InvalidSocketException If the stored socket resource is no socket resource + * @throws NoSocketErrorDetectedException If socket_last_error() gives zero back + * @todo Move all this socket-related stuff into own class, most of it resides in BaseListener + */ + public final function handleSocketError ($method, $line, array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('HUB-SYSTEM: Handling socket errorCode=%d - CALLED!', $this->getLastSocketError())); + + // This method handles only socket resources + if (!$this->isValidSocket()) { + // No resource, abort here + throw new InvalidSocketException(array($this, $this->getSocketResource()), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Check socket array, 1st element is mostly IP address (or file name), 2nd is port number + //* DEBUG-DIE: */ die(__METHOD__ . ':socketData=' . print_r($socketData, true)); + assert(isset($socketData[0])); + assert(isset($socketData[1])); + + // Get error code for first validation (0 is not an error) + $errorCode = $this->getLastSocketError(); + + // If the error code is zero, someone called this method without an error + if ($errorCode == 0) { + // No error detected (or previously cleared outside this method) + throw new NoSocketErrorDetectedException(array($this, $this->getSocketResource()), BaseListener::EXCEPTION_NO_SOCKET_ERROR); + } // END - if + + // Get handler (method) name + $handlerName = $this->getSocketErrorHandlerFromCode($errorCode); + + // Call-back the error handler method + call_user_func_array(array($this, $handlerName), array($this, $socketData)); + + // Finally clear the error because it has been handled + $this->clearLastSocketError(); } } diff --git a/application/hub/classes/factories/socket/class_SocketFactory.php b/application/hub/classes/factories/socket/class_SocketFactory.php index 18035de30..e20805b6a 100644 --- a/application/hub/classes/factories/socket/class_SocketFactory.php +++ b/application/hub/classes/factories/socket/class_SocketFactory.php @@ -104,13 +104,13 @@ class SocketFactory extends ObjectFactory { } /** - * Creates a Uni*-socket container instance from given listener + * Creates a listening Uni*-socket container instance from given listener * * @param $listenerInstance An instance of a Listenable class * @return $socketInstance An instance of a StorableSocket class * @throws InvalidSocketException If the socket cannot be completed */ - public static final function createFileSocket (Listenable $listenerInstance) { + public static final function createListenFileSocket (Listenable $listenerInstance) { // Create file name $socketFile = self::createTempPathForFile($listenerInstance->getConfigInstance()->getConfigEntry('ipc_socket_file_name')); @@ -147,7 +147,7 @@ class SocketFactory extends ObjectFactory { // Check if there was an error else if ($socketError > 0) { // Handle this socket error with a faked recipientData array - $listenerInstance->handleSocketError(__METHOD__, __LINE__, $socketInstance, array('null', '0')); + $socketInstance->handleSocketError(__METHOD__, __LINE__, array('null', '0')); } // END - if // Is the file there? @@ -168,21 +168,21 @@ class SocketFactory extends ObjectFactory { // Try to bind to it if (!$socketInstance->bindSocketTo($packageData[0])) { // Handle error here - $listenerInstance->handleSocketError(__METHOD__, __LINE__, $socketInstance, $packageData); + $socketInstance->handleSocketError(__METHOD__, __LINE__, $packageData); } // END - if // Start listen for connections self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER: Listening for connections.'); if (!$socketInstance->listenOnSocket()) { // Handle this socket error with a faked recipientData array - $listenerInstance->handleSocketError(__METHOD__, __LINE__, $socketInstance, $packageData); + $socketInstance->handleSocketError(__METHOD__, __LINE__, $packageData); } // END - if // Allow non-blocking I/O self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER: Setting non-blocking mode.'); if (!$socketInstance->enableSocketNonBlocking()) { // Handle this socket error with a faked recipientData array - $listenerInstance->handleSocketError(__METHOD__, __LINE__, $socketInstance, $packageData); + $socketInstance->handleSocketError(__METHOD__, __LINE__, $packageData); } // END - if // Return socket instance diff --git a/application/hub/classes/helper/connection/ipv4/class_BaseIpV4ConnectionHelper.php b/application/hub/classes/helper/connection/ipv4/class_BaseIpV4ConnectionHelper.php index 3bd764482..a12c47cfa 100644 --- a/application/hub/classes/helper/connection/ipv4/class_BaseIpV4ConnectionHelper.php +++ b/application/hub/classes/helper/connection/ipv4/class_BaseIpV4ConnectionHelper.php @@ -70,17 +70,12 @@ class BaseIpV4ConnectionHelper extends BaseConnectionHelper { * Initializes the current connection * * @return void - * @throws SocketOptionException If setting any socket option fails */ protected function initConnection () { // Set the option to reuse the port if (!$this->getSocketInstance()->enableReuseAddress()) { // Handle this socket error with a faked recipientData array - $this->handleSocketError(__METHOD__, __LINE__, $this->getSocketInstance(), array('0.0.0.0', '0')); - - // And throw again - // @TODO Move this to the socket error handler - throw new SocketOptionException(array($this, $this->getSocketInstance(), $socketError, $errorMessage), SocketHandler::EXCEPTION_INVALID_SOCKET); + $this->getSocketInstance()->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0')); } // END - if /* @@ -90,10 +85,7 @@ class BaseIpV4ConnectionHelper extends BaseConnectionHelper { */ if (!$this->getSocketInstance()->enableSocketNonBlocking()) { // Handle this socket error with a faked recipientData array - $helperInstance->handleSocketError(__METHOD__, __LINE__, $this->getSocketInstance(), array('0.0.0.0', '0')); - - // And throw again - throw new SocketOptionException(array($helperInstance, $this->getSocketInstance(), $socketError, $errorMessage), SocketHandler::EXCEPTION_INVALID_SOCKET); + $this->getSocketInstance()->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0')); } // END - if // Last step: mark connection as initialized diff --git a/application/hub/classes/listener/socket/class_SocketFileListener.php b/application/hub/classes/listener/socket/class_SocketFileListener.php index b3423ab08..b53d669a5 100644 --- a/application/hub/classes/listener/socket/class_SocketFileListener.php +++ b/application/hub/classes/listener/socket/class_SocketFileListener.php @@ -68,7 +68,7 @@ class SocketFileListener extends BaseListener implements Listenable { */ public function initListener () { // Create socket with factory - $socketInstance = SocketFactory::createFileSocket($this); + $socketInstance = SocketFactory::createListenFileSocket($this); // Set the main socket $this->registerServerSocketInstance($socketInstance); diff --git a/application/hub/classes/package/class_NetworkPackage.php b/application/hub/classes/package/class_NetworkPackage.php index 2146fe4df..aa01e2139 100644 --- a/application/hub/classes/package/class_NetworkPackage.php +++ b/application/hub/classes/package/class_NetworkPackage.php @@ -1027,9 +1027,6 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R if ($sentBytes === FALSE) { // Handle the error with a faked recipientData array $this->handleSocketError(__METHOD__, __LINE__, $encodedDataArray[self::RAW_SOCKET_INDEX], array('0.0.0.0', '0')); - - // And throw it - throw new InvalidSocketException(array($this, $encodedDataArray[self::RAW_SOCKET_INDEX], $socketError, $errorMessage), SocketHandler::EXCEPTION_INVALID_SOCKET); } elseif (($sentBytes === 0) && (strlen($encodedDataArray[self::RAW_ENCODED_DATA_INDEX]) > 0)) { // Nothing sent means we are done //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')'); diff --git a/application/hub/classes/pools/peer/class_DefaultPeerPool.php b/application/hub/classes/pools/peer/class_DefaultPeerPool.php index c4b9143e8..2e2d3db0e 100644 --- a/application/hub/classes/pools/peer/class_DefaultPeerPool.php +++ b/application/hub/classes/pools/peer/class_DefaultPeerPool.php @@ -86,7 +86,7 @@ class DefaultPeerPool extends BasePool implements PoolablePeer { // Is it without any errors? if ($errorCode > 0) { // Handle the socket error with a faked recipientData array - $this->handleSocketError(__METHOD__, __LINE__, $socketInstance, array('0.0.0.0', '0')); + $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0')); } // END - if } @@ -119,7 +119,7 @@ class DefaultPeerPool extends BasePool implements PoolablePeer { // Try to determine the peer's IP number if (!$peerName = $socketInstance->getSocketPeerName()) { // Handle the socket error with a faked recipientData array - $this->handleSocketError(__METHOD__, __LINE__, $socketInstance, array('0.0.0.0', '0')); + $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0')); } // END - if } else { // Server sockets won't work with socket_getpeername() @@ -257,7 +257,7 @@ class DefaultPeerPool extends BasePool implements PoolablePeer { // Try to get the "peer"'s name if (!$peerName = $socketArray[self::SOCKET_ARRAY_INSTANCE]->getSocketPeerName()) { // Handle the socket error with given package data - $this->handleSocketError(__METHOD__, __LINE__, $socketArray[self::SOCKET_ARRAY_INSTANCE], explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])); + $socketArray[self::SOCKET_ARRAY_INSTANCE]->handleSocketError(__METHOD__, __LINE__, explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])); } // END - if // Get diff --git a/application/hub/interfaces/class_HubInterface.php b/application/hub/interfaces/class_HubInterface.php index ed526ba0c..7ab9b035c 100644 --- a/application/hub/interfaces/class_HubInterface.php +++ b/application/hub/interfaces/class_HubInterface.php @@ -41,23 +41,6 @@ interface HubInterface extends FrameworkInterface { */ function ifStartEndMarkersSet ($data); - /** - * Handles socket error for given socket resource and peer data. This method - * validates socket resource stored in given container if it is a valid - * resource (see is_resource()) but assumes valid data in array - * $recipientData, except that count($recipientData) is always 2. - * - * @param $method Value of __METHOD__ from calling method - * @param $line Value of __LINE__ from calling method - * @param $socketInstance An instance of a StoreableSocket class - * @param $socketData A valid socket data array (0 = IP/file name, 1 = port) - * @return void - * @throws InvalidSocketException If the stored socket resource is no socket resource - * @throws NoSocketErrorDetectedException If socket_last_error() gives zero back - * @todo Move all this socket-related stuff into own class, most of it resides in BaseListener - */ - function handleSocketError ($method, $line, StorableSocket $socketInstance, array $socketData); - /** * Getter for listener pool instance * diff --git a/application/hub/interfaces/container/socket/class_StorableSocket.php b/application/hub/interfaces/container/socket/class_StorableSocket.php index 8f80383c4..49ee4659e 100644 --- a/application/hub/interfaces/container/socket/class_StorableSocket.php +++ b/application/hub/interfaces/container/socket/class_StorableSocket.php @@ -79,14 +79,41 @@ interface StorableSocket extends FrameworkInterface { * Getter for last socket error * * @return $lastSocketError Last socket error + * @throws InvalidSocketException If socket is valid */ function getLastSocketError (); /** * Tries to bind the socket. * + * @param $bindAddress Where to bind the socket to (e.g. Uni* socket file) * @return $result Result from binding socket + * @throws InvalidSocketException If socket is valid */ - function bindSocketTo (); + function bindSocketTo ($bindAddress); + + /** + * Tries to listen on the socket + * + * @return $result Result from listening on socket + * @throws InvalidSocketException If socket is valid + */ + function listenOnSocket (); + + /** + * Handles socket error for given socket resource and peer data. This method + * validates socket resource stored in given container if it is a valid + * resource (see is_resource()) but assumes valid data in array + * $recipientData, except that count($recipientData) is always 2. + * + * @param $method Value of __METHOD__ from calling method + * @param $line Value of __LINE__ from calling method + * @param $socketData A valid socket data array (0 = IP/file name, 1 = port) + * @return void + * @throws InvalidSocketException If the stored socket resource is no socket resource + * @throws NoSocketErrorDetectedException If socket_last_error() gives zero back + * @todo Move all this socket-related stuff into own class, most of it resides in BaseListener + */ + function handleSocketError ($method, $line, array $socketData); }