]> git.mxchange.org Git - hub.git/commitdiff
More rewrites:
authorRoland Häder <roland@mxchange.org>
Mon, 29 May 2017 15:56:08 +0000 (17:56 +0200)
committerRoland Häder <roland@mxchange.org>
Fri, 21 Aug 2020 16:50:09 +0000 (18:50 +0200)
- rewrote more parts towards SocketContainer/StorableStocket class/interface
- still UdpListener is half-finished
- added missing namespace
- imported BaseNodeHelper

Signed-off-by: Roland Häder <roland@mxchange.org>
21 files changed:
application/hub/classes/container/socket/class_SocketContainer.php
application/hub/classes/discovery/recipient/socket/class_PackageSocketDiscovery.php
application/hub/classes/factories/socket/class_SocketFactory.php
application/hub/classes/filter/task/node/class_NodeTaskHandlerInitializerFilter.php
application/hub/classes/helper/node/announcement/class_NodeAnnouncementHelper.php
application/hub/classes/helper/node/answer/class_BaseHubAnswerHelper.php
application/hub/classes/helper/node/class_
application/hub/classes/helper/node/class_BaseNodeHelper.php
application/hub/classes/helper/node/connection/class_NodeSelfConnectHelper.php
application/hub/classes/helper/node/requests/class_NodeRequestNodeListHelper.php
application/hub/classes/listener/class_BaseListener.php
application/hub/classes/listener/socket/class_SocketFileListener.php
application/hub/classes/listener/tcp/class_TcpListener.php
application/hub/classes/listener/udp/class_UdpListener.php
application/hub/classes/lists/pool/class_PoolEntriesList.php
application/hub/classes/pools/class_BasePool.php
application/hub/config.php
application/hub/interfaces/container/socket/class_StorableSocket.php
application/hub/interfaces/lookup/peer_states/class_LookupablePeerState.php
application/hub/interfaces/pool/class_Poolable.php
core

index 04c7b89e266160c3ab9d54aec3dd03dc58eeddab..f718d9ce9b582f95fc626badd02eb34202c12e0f 100644 (file)
@@ -4,6 +4,7 @@ namespace Hub\Container\Socket;
 
 // Import application-specific stuff
 use Hub\Handler\Network\RawData\BaseRawDataHandler;
+use Hub\Factory\Socket\SocketFactory;
 use Hub\Helper\Connection\BaseConnectionHelper;
 use Hub\Information\ShareableInfo;
 use Hub\Listener\BaseListener;
@@ -61,6 +62,11 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable
         */
        private $connectionTypes = array();
 
+       /**
+        * Timeout in usec for socket_select()
+        */
+       private $socketSelectTimeout = 0;
+
        /**
         * Protected constructor
         *
@@ -70,6 +76,9 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable
                // Call parent constructor
                parent::__construct(__CLASS__);
 
+               // Init value
+               $this->socketSelectTimeout = $this->getConfigInstance()->getConfigEntry('socket_select_timeout_usec');
+
                // Init array of connection types
                $this->connectionTypes = array(
                        StorableSocket::CONNECTION_TYPE_INCOMING,
@@ -421,7 +430,7 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable
                } // END - if
 
                // Tries to set option
-               $result = socket_set_option($this->getSocketResource(), SOL_SOCKET, SO_REUSEADDR, 1);
+               $result = $this->setSocketOption(SOL_SOCKET, SO_REUSEADDR, 1);
 
                // Return result
                return $result;
@@ -466,6 +475,144 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable
                $this->markConnectionShuttedDown();
        }
 
+       /**
+        * Checks whether the given connection type is valid
+        *
+        * @param       $connectionType         Type of connection, can be 'incoming', 'outgoing' or 'server'
+        * @return      $isValid                        Whether the provided connection type is valid
+        */
+       public function isValidConnectionType ($connectionType) {
+               // Is it valid?
+               $isValid = in_array($connectionType, $this->connectionTypes, TRUE);
+
+               // Return result
+               return $isValid;
+       }
+
+       /**
+        * Calls socket_select() on stored socket resource
+        *
+        * @return      $socketInstance         An instance of a StorableSocket class
+        * @throws      InvalidSocketException  If stored socket is invalid
+        */
+       public function acceptNewIncomingSocket () {
+               // Should be valid socket
+               if (!$this->isValidSocket()) {
+                       // Throw exception
+                       throw new InvalidSocketException(array($this, $this->getSocketResource()), self::EXCEPTION_INVALID_SOCKET);
+               } // END - if
+
+               // Init all arrays, at least readers
+               $readers = array($this->getSocketResource());
+               $writers = array();
+               $excepts = array();
+
+               // Check if we have some peers left
+               $left = socket_select(
+                       $readers,
+                       $writers,
+                       $excepts,
+                       0,
+                       $this->socketSelectTimeout
+               );
+
+               // Some new peers found?
+               if ($left < 1) {
+                       // Debug message
+                       //* EXTREME-NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: left=' . $left . ',serverSocket=' . $this->getSocketResource() . ',readers=' . print_r($readers, true));
+
+                       // Nothing new found
+                       return NULL;
+               } // END - if
+
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: serverSocket=' . $this->getSocketResource() . ',readers=' . print_r($readers, true));
+
+               // Do we have changed peers?
+               if (!in_array($this->getSocketResource(), $readers)) {
+                       // Abort here
+                       return NULL;
+               } // END - if
+
+               /*
+                * Then accept it, if this socket is set to non-blocking IO and the
+                * connection is NOT sending any data, socket_read() may throw
+                * error 11 (Resource temporary unavailable). This really nasty
+                * because if you have blocking IO socket_read() will wait and wait
+                * and wait ...
+                */
+               $socketResource = socket_accept($this->getSocketResource());
+
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: socketResource=' . $socketResource . ',serverSocket=' .$this->getSocketResource());
+
+               // Create socket instance from it
+               $socketInstance = SocketFactory::createIncomingSocketInstance($socketResource, $this->getSocketProtocol());
+
+               // Return accepted socket instance
+               return $socketInstance;
+       }
+
+       /**
+        * Tries to identify the socket peer by calling socket_getpeer() and stores
+        * it in package data array.
+        *
+        * @return      $result         Whether identifying socket peer was successfull
+        */
+       public function identifySocketPeer () {
+               // Init peer address (IP)/port
+               $peerAddress = '0.0.0.0';
+               $peerPort    = '0';
+
+               // Call other method
+               $result = $this->getSocketPeerName($peerAddress, $peerPort);
+
+               // Valid?
+               if ($result === TRUE) {
+                       // Get package data
+                       $packageData = $this->getPackageData();
+
+                       // Set both
+                       $packageData[StorableSocket::SOCKET_ARRAY_INDEX_ADDRESS] = $peerAddress;
+                       $packageData[StorableSocket::SOCKET_ARRAY_INDEX_PORT]    = $peerPort;
+
+                       // Set it back
+                       $this->setPackageData($packageData);
+               } // END - if
+
+               // Return result
+               return $result;
+       }
+
+       /**
+        * Tries to set socket timeout option
+        *
+        * @return      $result         Whether the option has been set
+        */
+       public function setSocketTimeoutOptions () {
+               // Array for timeout settings
+               $options  = array(
+                       // Seconds
+                       'sec'  => $this->getConfigInstance()->getConfigEntry($this->getSocketProtocol() . '_socket_accept_wait_sec'),
+                       // Milliseconds
+                       'usec' => $this->getConfigInstance()->getConfigEntry($this->getSocketProtocol() . '_socket_accept_wait_usec')
+               );
+
+               // Call inner method
+               $result = $this->setSocketOption(SOL_SOCKET, SO_RCVTIMEO, $options);
+
+               // Return result
+               return $result;
+       }
+
+       /**
+        * Tries to enable out-of-band (OOB) data
+        *
+        * @return      $result         Whether OOB has been enabled
+        */
+       public function enableSocketOutOfBandData () {
+       }
+
        /**
         * Handles socket error for given socket resource and peer data. This method
         * validates socket resource stored in given container if it is a valid
@@ -816,6 +963,32 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable
                $this->socketProtocol = $socketProtocol;
        }
 
+       /**
+        * Tries to set given socket option
+        *
+        * @param       $level                  Level to set, e.g. use SOL_SOCKET
+        * @param       $optionName             Option name to set
+        * @param       $optionValue    Option value to set
+        * @return      $result                 Whether calling socket_set_option() was successfull
+        * @throws      InvalidSocketException  If stored socket is invalid
+        */
+       private function setSocketOption ($level, $optionName, $optionValue) {
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: level=%s,optionName=%s,optionValue[%s]=%s - CALLED!', strtoupper($this->getSocketProtocol()), $level, $optionName, gettype($optionValue), $optionValue));
+
+               // Should be valid socket
+               if (!$this->isValidSocket()) {
+                       // Throw exception
+                       throw new InvalidSocketException(array($this, $this->getSocketResource()), self::EXCEPTION_INVALID_SOCKET);
+               } // END - if
+
+               // Set it
+               $result = socket_set_option($this->getSocketResource(), $level, $optionName, $optionValue);
+
+               // Return result
+               return $result;
+       }
+
        /**
         * Clears last socket error
         *
@@ -843,18 +1016,4 @@ class SocketContainer extends BaseContainer implements StorableSocket, Visitable
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: Error cleared - EXIT!');
        }
 
-       /**
-        * Checks whether the given connection type is valid
-        *
-        * @param       $connectionType         Type of connection, can be 'incoming', 'outgoing' or 'server'
-        * @return      $isValid                        Whether the provided connection type is valid
-        */
-       public function isValidConnectionType ($connectionType) {
-               // Is it valid?
-               $isValid = in_array($connectionType, $this->connectionTypes, TRUE);
-
-               // Return result
-               return $isValid;
-       }
-
 }
index 177c8d82141214a755d4097d326f56835fe3330a..ed2fd132fb57a279d57851ab2e68140188762099 100644 (file)
@@ -90,14 +90,14 @@ class PackageSocketDiscovery extends BaseRecipientDiscovery implements Discovera
                $protocolName = $protocolInstance->getProtocolName();
 
                // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-DISCOVERY: protocolName=' . $protocolName . ',poolEntriesInstance=' . $poolInstance->getPoolEntriesInstance()->__toString());
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-DISCOVERY: protocolName=' . $protocolName);
 
                /*
                 * Now we need to choose again. It is whether we are speaking with a hub
                 * or with a client. So just handle it over to all listeners in this
                 * pool.
                 */
-               foreach ($poolInstance->getPoolEntriesInstance()->getArrayFromList($protocolName) as $listenerInstance) {
+               foreach ($poolInstance->getArrayFromList($protocolName) as $listenerInstance) {
                        // Debug output
                        //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-DISCOVERY: protocolName=' . $protocolName . ',listenerInstance[' . gettype($listenerInstance) . ']=' . $listenerInstance);
 
index cae3daeef90b248c64db45e2fe7d04a32e9173b5..1fb67772c6419232d737cd19b7359bb696676af2 100644 (file)
@@ -8,6 +8,7 @@ use Hub\Handler\Protocol\HandleableProtocol;
 use Hub\Listener\BaseListener;
 use Hub\Listener\Listenable;
 use Hub\Network\Package\NetworkPackage;
+use Hub\Pool\Poolable;
 
 // Import framework stuff
 use CoreFramework\Bootstrap\FrameworkBootstrap;
@@ -16,6 +17,9 @@ use CoreFramework\Factory\ObjectFactory;
 use CoreFramework\Registry\Registry;
 use CoreFramework\Socket\InvalidSocketException;
 
+// Import SPL stuff
+use \LogicException;
+
 /**
  * A socket factory class
  *
@@ -364,4 +368,108 @@ class SocketFactory extends ObjectFactory {
                return $socketInstance;
        }
 
+       /**
+        * Creates a socket from given pool instance by calling socket_accept() on
+        * the pooled listening socket. If socket_select() has found no changes,
+        * NULL is being returned
+        *
+        * @param       $poolInstance   An instance of a Poolable class
+        * @param       $socketInstance         The listening instance of a StorableSocket
+        * @return      $socketInstance         A new instance of a StorableSocket or NULL if no changes has been detected.
+        * @throws      LogicException  If the current instance is not valid
+        */
+       public static final function createNextAcceptedSocketFromPool (Poolable $poolInstance, StorableSocket $socketInstance) {
+               // Is the an iterator instance?
+               if (!Registry::getRegistry()->instanceExists('pool_iterator')) {
+                       // Create iterator instance
+                       $iteratorInstance = $poolInstance->createListIteratorInstance('pool');
+
+                       // Now store it in registry
+                       Registry::getRegistry()->addInstance('pool_iterator', $iteratorInstance);
+               } else {
+                       // Get iterator from registry
+                       $iteratorInstance = Registry::getRegistry()->getInstance('pool_iterator');
+               }
+
+               // Is it valid?
+               if (!$iteratorInstance->valid()) {
+                       // Try to rewind it
+                       $iteratorInstance->rewind();
+               } // END - if
+
+               // Get current socket instance
+               $current = $iteratorInstance->current();
+
+               // Make sure it is valid
+               if (!is_array($current)) {
+                       // Opps, should not happen
+                       throw new LogicException(sprintf('current[]=%s is not an array.', gettype($current)));
+               } elseif (!isset($current[Poolable::SOCKET_ARRAY_INSTANCE])) {
+                       // Not set
+                       throw new LogicException(sprintf('current[%s] is not set.', Poolable::SOCKET_ARRAY_INSTANCE));
+               } elseif (!isset($current[Poolable::SOCKET_ARRAY_CONN_TYPE])) {
+                       // Not set
+                       throw new LogicException(sprintf('current[%s] is not set.', Poolable::SOCKET_ARRAY_CONN_TYPE));
+               } elseif ($current[Poolable::SOCKET_ARRAY_CONN_TYPE] != StorableSocket::CONNECTION_TYPE_SERVER) {
+                       // Not expected type
+                       throw new LogicException(sprintf('current[%s]=%s is not expected: %s', Poolable::SOCKET_ARRAY_CONN_TYPE, $current[Poolable::SOCKET_ARRAY_CONN_TYPE], StorableSocket::CONNECTION_TYPE_SERVER));
+               }
+
+               // Try to accept a new (incoming) socket from current listener instance
+               $acceptedSocketInstance = $current[Poolable::SOCKET_ARRAY_INSTANCE]->acceptNewIncomingSocket();
+
+               // Return found socket instance
+               return $acceptedSocketInstance;
+       }
+
+       /**
+        * Creates a StorableSocket instance from given socket resource
+        *
+        * @param       $socketResource         Valid socket resource from calling socket_accept()
+        * @param       $socketProtocol         Protcol of socket (e.g. 'tcp', 'udp', see StorableSocket interface for valid values
+        * @return      $socketInstance         An instance of a StorableSocket class
+        */
+       public static final function createIncomingSocketInstance ($socketResource, $socketProtocol) {
+               // Fake package data array (must be set later on)
+               $packageData = array(
+                       StorableSocket::SOCKET_ARRAY_INDEX_ADDRESS => 'invalid',
+                       StorableSocket::SOCKET_ARRAY_INDEX_PORT    => '0',
+               );
+
+               // Create socket instance
+               $socketInstance = self::createObjectByConfiguredName('socket_container_class', array($socketResource, $socketProtocol, $packageData, NULL));
+
+               // Is the socket resource valid?
+               if (!$socketInstance->isValidSocket()) {
+                       // Something bad happened
+                       throw new InvalidSocketException(array($listenerInstance, $socketInstance), self::EXCEPTION_INVALID_SOCKET);
+               } // END - if
+
+               // Try to identify socket peer
+               if (!$socketInstance->identifySocketPeer()) {
+                       // Handle this socket error with a faked recipientData array
+                       $socketInstance->handleSocketEror(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+               } // END - if
+
+               // Set timeout to configured seconds
+               if (!$socketinstance->setSocketTimeoutOptions()) {
+                       // Handle this socket error with a faked recipientData array
+                       $socketInstance->handleSocketEror(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+               } // END - if
+
+               // Enable SO_OOBINLINE
+               if (!$socketInstance->enableSocketOutOfBandData()) {
+                       // Handle this socket error with a faked recipientData array
+                       $socketInstance->handleSocketEror(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+               } // END - if
+
+               // Set non-blocking
+               if (!$socketInstance->enableSocketNonBlocking()) {
+                       // Handle this socket error with a faked recipientData array
+                       $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+               } // END - if
+
+               // Return found socket instance
+               return $socketInstance;
+       }
 }
index 5d60f98bb9d1bfbd88a6459cb7f70b194adf1591..d55ba25ccf36ffd3dab7cd2af13dce8245dea904 100644 (file)
@@ -150,7 +150,7 @@ class NodeTaskHandlerInitializerFilter extends BaseNodeFilter implements Filtera
                // Register it
                $handlerInstance->registerTask('update_check', $taskInstance);
 
-               // Get the list instance here
+               // Get list instance here
                $listInstance = $nodeInstance->getListenerPoolInstance()->getPoolEntriesInstance();
 
                // Prepare a ping task
@@ -166,7 +166,5 @@ class NodeTaskHandlerInitializerFilter extends BaseNodeFilter implements Filtera
                 */
                $nodeInstance->addExtraTasks($handlerInstance);
        }
-}
 
-// [EOF]
-?>
+}
index 1df415462bf87d942f25207653b545eab0d282d9..003985fdbdba099b5911d4465c484de0d867d5a1 100644 (file)
@@ -4,6 +4,7 @@ namespace Hub\Node\Helper\Announcement;
 
 // Import application-specific stuff
 use Hub\Factory\Network\NetworkPackageFactory;
+use Hub\Helper\Node\BaseNodeHelper;
 use Hub\Helper\Node\NodeHelper;
 use Hub\Network\Package\NetworkPackage;
 
index 2d699f18ee13091f7beb60c471bde3443ecf8925..89d5c0a88517a33caaab4066c8f11b14771243aa 100644 (file)
@@ -1,4 +1,10 @@
 <?php
+// Own namespace
+namespace Helper\Node\Answer;
+
+// Import application-specific stuff
+use Hub\Helper\Node\BaseNodeHelper;
+
 /**
  * A general hub message answer helper class
  *
index f00c3871a1ba8bc206109c4ac7b5845384e7d80c..87a2b3bbfab2148c89ed1d2f9595dfeb176679d9 100644 (file)
@@ -4,6 +4,7 @@ namespace Hub\Node\Helper\;
 
 // Import application-specific stuff
 use Hub\Factory\Network\NetworkPackageFactory;
+use Hub\Helper\Node\BaseNodeHelper;
 use Hub\Helper\Node\NodeHelper;
 use Hub\Network\Package\NetworkPackage;
 
index 36b534de8b842b3b643f2d83e9c7b18b7cda203a..dfe6bac553eaffcfd55695acebda2624431b2f15 100644 (file)
@@ -39,7 +39,5 @@ class BaseNodeHelper extends BaseHubSystemHelper {
                // Call parent constructor
                parent::__construct($className);
        }
-}
 
-// [EOF]
-?>
+}
index 5ec6c8dca18414d7b9ee87f537524954b1024671..59bba147339e2a5e9c6ac101a9a6fa228fd947df 100644 (file)
@@ -4,6 +4,7 @@ namespace Hub\Node\Helper\SelfConnect;
 
 // Import application-specific stuff
 use Hub\Factory\Network\NetworkPackageFactory;
+use Hub\Helper\Node\BaseNodeHelper;
 use Hub\Helper\Node\NodeHelper;
 use Hub\Network\Package\NetworkPackage;
 use Hub\Tag\Tagable;
index 9d5880a7577865786ddd79a378c45c76ac8c8883..f1ae9860da09775a19a1865c0f25193d65253d47 100644 (file)
@@ -4,6 +4,7 @@ namespace Hub\Node\Helper\Request\NodeList;
 
 // Import application-specific stuff
 use Hub\Factory\Network\NetworkPackageFactory;
+use Hub\Helper\Node\BaseNodeHelper;
 use Hub\Helper\Node\NodeHelper;
 use Hub\Network\Package\NetworkPackage;
 
index 9c8902227ae93f36d37fc4b6ec234cdeeec4f341..f367f33cc3d368dce642ec39326e3c97db3ade6b 100644 (file)
@@ -6,6 +6,7 @@ namespace Hub\Listener;
 use Hub\Container\Socket\StorableSocket;
 use Hub\Factory\Information\Connection\ConnectionInfoFactory;
 use Hub\Factory\Node\NodeObjectFactory;
+use Hub\Factory\Socket\SocketFactory;
 use Hub\Generic\BaseHubSystem;
 use Hub\Network\Package\NetworkPackage;
 use Hub\Pool\Peer\PoolablePeer;
@@ -260,116 +261,47 @@ class BaseListener extends BaseHubSystem implements Visitable {
                assert($this->getPoolInstance() instanceof Poolable);
                assert($this->getSocketInstance()->isValidSocket());
 
-               // Get all readers
-               $readers = $this->getPoolInstance()->getAllSingleSockets();
-               $writers = array();
-               $excepts = array();
-               die('readers='.print_r($readers, TRUE));
-
-               // Check if we have some peers left
-               $left = socket_select(
-                       $readers,
-                       $writers,
-                       $excepts,
-                       0,
-                       150
-               );
-
-               // Some new peers found?
-               if ($left < 1) {
-                       // Debug message
-                       //* EXTREME-NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('TCP-LISTENER: left=' . $left . ',serverSocket=' . $this->getSocketInstance() . ',readers=' . print_r($readers, true));
+               // Get next socket instance from pool over the factory
+               $socketInstance = SocketFactory::createNextAcceptedSocketFromPool($this->getPoolInstance(), $this->getSocketInstance());
 
-                       // Nothing new found
+               // Is socket instance set?
+               if (!($socketInstance instanceof StorableSocket)) {
+                       // Nothing has changed on the listener
                        return;
                } // END - if
 
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('TCP-LISTENER: serverSocket=' . $this->getSocketInstance() . ',readers=' . print_r($readers, true));
-
-               // Do we have changed peers?
-               if (in_array($this->getSocketInstance(), $readers)) {
-                       /*
-                        * Then accept it, if this socket is set to non-blocking IO and the
-                        * connection is NOT sending any data, socket_read() may throw
-                        * error 11 (Resource temporary unavailable). This really nasty
-                        * because if you have blocking IO socket_read() will wait and wait
-                        * and wait ...
-                        */
-                       $newSocket = socket_accept($this->getSocketInstance());
-
-                       // Debug message
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('TCP-LISTENER: newSocket=' . $newSocket . ',serverSocket=' .$this->getSocketInstance());
-
-                       // Array for timeout settings
-                       $options  = array(
-                               // Seconds
-                               'sec'  => $this->getConfigInstance()->getConfigEntry('tcp_socket_accept_wait_sec'),
-                               // Milliseconds
-                               'usec' => $this->getConfigInstance()->getConfigEntry('tcp_socket_accept_wait_usec')
-                       );
-
-                       // Set timeout to configured seconds
-                       // @TODO Does this work on Windozer boxes???
-                       if (!socket_set_option($newSocket, SOL_SOCKET, SO_RCVTIMEO, $options)) {
-                               // Handle this socket error with a faked recipientData array
-                               $this->handleSocketError(__METHOD__, __LINE__, $newSocket, array('0.0.0.0', '0'));
-                       } // END - if
-
-                       // Output result (only for debugging!)
-                       /*
-                       $option = socket_get_option($newSocket, SOL_SOCKET, SO_RCVTIMEO);
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SO_RCVTIMEO[' . gettype($option) . ']=' . print_r($option, true));
-                       */
-
-                       // Enable SO_OOBINLINE
-                       if (!socket_set_option($newSocket, SOL_SOCKET, SO_OOBINLINE ,1)) {
-                               // Handle this socket error with a faked recipientData array
-                               $this->handleSocketError(__METHOD__, __LINE__, $newSocket, array('0.0.0.0', '0'));
-                       } // END - if
-
-                       // Set non-blocking
-                       if (!socket_set_nonblock($newSocket)) {
-                               // Handle this socket error with a faked recipientData array
-                               $this->handleSocketError(__METHOD__, __LINE__, $newSocket, array('0.0.0.0', '0'));
-                       } // END - if
-
-                       // Add it to the peers
-                       $this->getPoolInstance()->addPeer($newSocket, StorableSocket::CONNECTION_TYPE_INCOMING);
-
-                       // Init peer address/port
-                       $peerAddress = '0.0.0.0';
-                       $peerPort    = '0';
-
-                       // Get peer name
-                       if (!socket_getpeername($newSocket, $peerAddress, $peerPort)) {
-                               // Handle this socket error with a faked recipientData array
-                               $this->handleSocketError(__METHOD__, __LINE__, $newSocket, array('0.0.0.0', '0'));
-                       } // END - if
-
-                       // Get node instance
-                       $nodeInstance = NodeObjectFactory::createNodeInstance();
-
-                       // Create a faked package data array
-                       $packageData = array(
-                               NetworkPackage::PACKAGE_DATA_SENDER    => $peerAddress . $peerSuffix,
-                               NetworkPackage::PACKAGE_DATA_RECIPIENT => $nodeInstance->getSessionId(),
-                               NetworkPackage::PACKAGE_DATA_STATUS    => NetworkPackage::PACKAGE_STATUS_FAKED
-                       );
-
-                       // Get a connection info instance
-                       $infoInstance = ConnectionInfoFactory::createConnectionInfoInstance($this->getProtocolName(), 'listener');
-
-                       // Will the info instance with listener data
-                       $infoInstance->fillWithListenerInformation($this);
-
-                       // Get a socket registry
-                       $registryInstance = SocketRegistryFactory::createSocketRegistryInstance();
-
-                       // Register the socket with the registry and with the faked array
-                       $registryInstance->registerSocketInstance($infoInstance, $newSocket, $packageData);
+               // Init peer address/port
+               $peerAddress = '0.0.0.0';
+               $peerPort    = '0';
+
+               // Get peer name
+               if (!$socketInstance->getSocketPeerName($peerAddress, $peerPort)) {
+                       // Handle this socket error with a faked recipientData array
+                       $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0'));
                } // END - if
 
+               // Get node instance
+               $nodeInstance = NodeObjectFactory::createNodeInstance();
+
+               // Create a faked package data array
+               $packageData = array(
+                       NetworkPackage::PACKAGE_DATA_SENDER    => $peerAddress . $peerSuffix,
+                       NetworkPackage::PACKAGE_DATA_RECIPIENT => $nodeInstance->getSessionId(),
+                       NetworkPackage::PACKAGE_DATA_STATUS    => NetworkPackage::PACKAGE_STATUS_FAKED
+               );
+
+               // Get a connection info instance
+               $infoInstance = ConnectionInfoFactory::createConnectionInfoInstance($this->getProtocolName(), 'listener');
+
+               // Will the info instance with listener data
+               $infoInstance->fillWithListenerInformation($this);
+
+               // Get a socket registry
+               $registryInstance = SocketRegistryFactory::createSocketRegistryInstance();
+
+               // Register the socket with the registry and with the faked array
+               $registryInstance->registerSocketInstance($infoInstance, $socketInstance, $packageData);
+
                // Do we have to rewind?
                if (!$this->getIteratorInstance()->valid()) {
                        // Rewind the list
index 10abef303201ff9ef708ff3953eddea07373d848..002b09486e6718be4975edcd4394518f2df3de58 100644 (file)
@@ -83,7 +83,7 @@ class SocketFileListener extends BaseListener implements Listenable {
                $this->setPoolInstance($poolInstance);
 
                // Initialize iterator for listening on packages
-               $iteratorInstance = ObjectFactory::createObjectByConfiguredName('socket_listen_iterator_class', array($poolInstance->getPoolEntriesInstance()));
+               $iteratorInstance = $poolInstance->createListIteratorInstance('socket_listen');
 
                // Rewind it and remember it in this class
                $iteratorInstance->rewind();
index 6d09063ef89cbed84b6619a12074d33241f4cd7c..04497715fc0d95369d0113b74aa07059f55fe087 100644 (file)
@@ -83,7 +83,7 @@ class TcpListener extends BaseListener implements Listenable {
                $this->setPoolInstance($poolInstance);
 
                // Initialize iterator for listening on packages
-               $iteratorInstance = ObjectFactory::createObjectByConfiguredName('network_listen_iterator_class', array($poolInstance->getPoolEntriesInstance()));
+               $iteratorInstance = $poolInstance->createListIteratorInstance('network_listen');
 
                // Rewind it and remember it in this class
                $iteratorInstance->rewind();
@@ -120,7 +120,5 @@ class TcpListener extends BaseListener implements Listenable {
                // Please don't call this
                throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
        }
-}
 
-// [EOF]
-?>
+}
index ec41c1c262979fe3a8379b80b24f721ff80f99ac..5c9dc4aaa26ad4753bb91121416498a7b8ba7704 100644 (file)
@@ -89,11 +89,14 @@ class UdpListener extends BaseListener implements Listenable {
         * @todo        ~50% done
         */
        public function doListen() {
+               $this->partialStub('Please rewrite this part.');
+               return;
+
                // Read a package and determine the peer
                $amount = @socket_recvfrom($this->getSocketInstance(), $rawData, $this->getConfigInstance()->getConfigEntry('udp_buffer_length'), MSG_DONTWAIT, $peer, $port);
 
                // Get last error
-               $lastError = socket_last_error($this->getSocketInstance());
+               $lastError = $this->getSocketInstance()->getSocketLastErrorCode();
 
                // Do we have an error at the line?
                if ($lastError == 11) {
@@ -103,7 +106,7 @@ class UdpListener extends BaseListener implements Listenable {
                         * "listener" won't read any packages except if the UDP sender
                         * starts the transmission before this "listener" came up...
                         */
-                       socket_clear_error($this->getSocketInstance());
+                       $this->getSocketInstance()->clearLastSocketError();
 
                        // Skip further processing
                        return;
index f8c394ebd9bf0470469e7e3c0312acd819ebc7ef..4745e932125054216a1e2351adca7ec25389befe 100644 (file)
@@ -81,7 +81,5 @@ class PoolEntriesList extends BaseList implements Listable {
                // Clear the only one group
                $this->clearGroup('pool');
        }
-}
 
-// [EOF]
-?>
+}
index 37bb412775d78098884b4858123b9be35188f52e..837d47f468ff59ef16e5a429b6a740b89aa3065f 100644 (file)
@@ -54,15 +54,6 @@ abstract class BasePool extends BaseHubSystem implements Poolable, Visitable {
                $this->poolEntriesInstance = ObjectFactory::createObjectByConfiguredName('pool_entries_list_class');
        }
 
-       /**
-        * Getter for pool entries instance
-        *
-        * @return      $poolEntriesInstance    An instance for pool entries (list)
-        */
-       public final function getPoolEntriesInstance () {
-               return $this->poolEntriesInstance;
-       }
-
        /**
         * Adds an instance to a pool segment
         *
@@ -101,6 +92,29 @@ abstract class BasePool extends BaseHubSystem implements Poolable, Visitable {
                $this->getPoolEntriesInstance()->addEntry('pool', $poolEntry);
        }
 
+       /**
+        * Gets the array from specified list
+        *
+        * @param       $list   The list identifier we should return
+        * @return      $array  The requested array
+        */
+       protected final function getArrayFromList ($list) {
+               // Get the array
+               $array = $this->getPoolEntriesInstance()->getArrayFromList($list);
+
+               // Return it
+               return $array;
+       }
+
+       /**
+        * Getter for pool entries instance
+        *
+        * @return      $poolEntriesInstance    An instance for pool entries (list)
+        */
+       public final function getPoolEntriesInstance () {
+               return $this->poolEntriesInstance;
+       }
+
        /**
         * Accepts the visitor to process the visit "request"
         *
@@ -152,20 +166,6 @@ abstract class BasePool extends BaseHubSystem implements Poolable, Visitable {
                //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('POOL: ' . $visitorInstance->__toString() . ' has visited - EXIT!');
        }
 
-       /**
-        * Gets the array from specified list
-        *
-        * @param       $list   The list identifier we should return
-        * @return      $array  The requested array
-        */
-       protected final function getArrayFromList ($list) {
-               // Get the array
-               $array = $this->getPoolEntriesInstance()->getArrayFromList($list);
-
-               // Return it
-               return $array;
-       }
-
        /**
         * Run the pre-shutdown seqeuence by a visitor pattern
         *
@@ -185,4 +185,18 @@ abstract class BasePool extends BaseHubSystem implements Poolable, Visitable {
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('POOL: Shutting down listener pool - EXIT!');
        }
 
+       /**
+        * Creates an iterator instance from inner list instance
+        *
+        * @param       $poolType       Pool type (e.g. socket_listen)
+        * @return      $iteratorInstance       An instance of a Iterator class
+        */
+       public function createListIteratorInstance ($poolType) {
+               // Create iterator instance
+               $iteratorInstance = ObjectFactory::createObjectByConfiguredName($poolType . '_iterator_class', array($this->getPoolEntriesInstance()));
+
+               // Return it
+               return $iteratorInstance;
+       }
+
 }
index 466580767190df8ff2a88686a19d1f799b4b04b2..89f6d8e528ee1fdab130fb178a1f27868cc08cc0 100644 (file)
@@ -102,6 +102,9 @@ $cfg->setConfigEntry('application_pool_class', 'Hub\Pool\Peer\DefaultPeerPool');
 // CFG: POOL-ENTRIES-LIST-CLASS
 $cfg->setConfigEntry('pool_entries_list_class', 'Hub\Lists\Pool\PoolEntriesList');
 
+// CFG: POOL-ITERATOR-CLASS
+$cfg->setConfigEntry('pool_iterator_class', 'CoreFramework\Iterator\DefaultIterator');
+
 // CFG: SHUTDOWN-POOL-ITERATOR-CLASS
 $cfg->setConfigEntry('shutdown_pool_iterator_class', 'ShutdownPoolIterator');
 
@@ -142,7 +145,7 @@ $cfg->setConfigEntry('active_task_visitor_class', 'Hub\Visitor\Task\Active\Activ
 $cfg->setConfigEntry('node_announcement_helper_class', 'NodeAnnouncementHelper');
 
 // CFG: NODE-SELF-CONNECT-HELPER-CLASS
-$cfg->setConfigEntry('node_self_connect_helper_class', 'NodeSelfConnectHelper');
+$cfg->setConfigEntry('node_self_connect_helper_class', 'Hub\Node\Helper\SelfConnect\NodeSelfConnectHelper');
 
 // CFG: DHT-BOOTSTRAP-HELPER-CLASS
 $cfg->setConfigEntry('dht_bootstrap_helper_class', 'Hub\Helper\Dht\Bootstrap\DhtBootstrapHelper');
@@ -820,6 +823,9 @@ $cfg->setConfigEntry('socket_timeout_seconds', 3);
 // CFG: SOCKET-TIMEOUT-MICROSECONDS
 $cfg->setConfigEntry('socket_timeout_microseconds', 0);
 
+// CFG: SOCKET-SELECT-TIMEOUT-USEC
+$cfg->setConfigEntry('socket_select_timeout_usec', 50);
+
 // CFG: CHUNK-HANDLER-CLASS
 $cfg->setConfigEntry('chunk_handler_class', 'Hub\Handler\Network\RawData\Chunks\ChunkHandler');
 
index 09687e8f20997d26f4c7f619fb7f8465c2addbce..67797780d8bf434494889d0377ff9d842aa5ae78 100644 (file)
@@ -116,6 +116,35 @@ interface StorableSocket extends FrameworkInterface {
         */
        function getSocketPeerName (&$peerAddress, &$peerPort);
 
+       /**
+        * Calls socket_select() on stored socket resource
+        *
+        * @return      $socketInstance         An instance of a StorableSocket class
+        * @throws      InvalidSocketException  If stored socket is invalid
+        */
+       function acceptNewIncomingSocket ();
+
+       /**
+        * Tries to identify the socket peer by calling socket_getpeer()
+        *
+        * @return      $result         Whether the peer has been identified
+        */
+       function identifySocketPeer();
+
+       /**
+        * Tries to set socket timeout option
+        *
+        * @return      $result         Whether the option has been set
+        */
+       function setSocketTimeoutOptions();
+
+       /**
+        * Tries to enable out-of-band (OOB) data
+        *
+        * @return      $result         Whether OOB has been enabled
+        */
+       function enableSocketOutOfBandData();
+
        /**
         * Getter for socket procotol field
         *
index 3184887b4ac6c8e37da85ca3e7f8ea4340884216..7385a22e5b3f19939096eeb827806c5541507128 100644 (file)
@@ -3,6 +3,7 @@
 namespace Hub\State\Peer\Lookup;
 
 // Import application-specific stuff
+use Hub\Container\Socket\StorableSocket;
 use Hub\Helper\Connection\ConnectionHelper;
 
 // Import framework stuff
@@ -43,10 +44,10 @@ interface LookupablePeerState extends Lookupable {
         * Registers a peer with given package data. We use the session id from it
         *
         * @param       $packageData            Valid raw package data
-        * @param       $socketResource         A valid socket resource
-        * @return<>void
+        * @param       $socketInstance         An instance of a StorableSocket class
+        * @return      void
         */
-       function registerPeerByPackageData (array $packageData, $socketResource);
+       function registerPeerByPackageData (array $packageData, StorableSocket $socketInstance);
 
        /**
         * Registers the given peer state and raw package data
index 653421a32dbf2989d897f9b02999b73de1b1b89d..5f764a0cfdccd98bc7eef5f237910f2951e78fc3 100644 (file)
@@ -28,12 +28,17 @@ use Hub\Generic\HubInterface;
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 interface Poolable extends HubInterface {
-       /**
-        * Socket array elements
-        */
+       // Socket array elements
        const SOCKET_ARRAY_INSTANCE  = 'instance';
        const SOCKET_ARRAY_CONN_TYPE = 'connection_type';
 
+       /**
+        * Getter for pool entries instance
+        *
+        * @return      $poolEntriesInstance    An instance for pool entries (list)
+        */
+       function getPoolEntriesInstance ();
+
        /**
         * Pre-shuts down the pool
         *
@@ -41,4 +46,12 @@ interface Poolable extends HubInterface {
         */
        function preShutdown ();
 
+       /**
+        * Creates an iterator from inner list instance.
+        *
+        * @param       $poolType       Pool type (e.g. 'socket_listen', 'network_listen')
+        * @return      $iteratorInstance       An instance of a Iterator class
+        */
+       function createListIteratorInstance ($poolType);
+
 }
diff --git a/core b/core
index 5301f9dd1ac83bc13ebfedda721477ec0405e228..ba6776b5d9b04fd6916224c088cabf255643c6d7 160000 (submodule)
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit 5301f9dd1ac83bc13ebfedda721477ec0405e228
+Subproject commit ba6776b5d9b04fd6916224c088cabf255643c6d7