* @version 0.0 * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software * @license GNU GPL 3.0 or any newer version * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ class HubConnector extends BaseFrameworkSystem { /** * The socket we shall use for communication */ private $socketResource = null; /** * The peer instance (HubPeer class) */ private $peerInstance = null; /** * The private constructor * * @return void */ protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); // Set description $this->setObjectDescription("Hub-Connector"); // Set unique ID $this->createUniqueID(); // Tidy up a little $this->removeSystemArray(); $this->removeNumberFormaters(); } /** * Creates an instance based on the (IP) address and port number of this * class. Next it tries to connect to the specified peer and communicates * to it over a socket * * @param $address The peer's IP address * @param $port The peer's port number * @param $hubInstance An instance of a HubCoreLoop class * @return $connector An instance of this class * @throws HubHelloException If HELLO retries reached maximum */ public final static function createHubConnectorByAddressPort ($address, $port, HubCoreLoop $hubInstance) { // Get a new instance of this class $connector = new HubConnector(); // Connect to the given address and IP number $connector->aquireConnectionToAddress($address, $port); // Message to console $hubInstance->getOutputInstance()->output(sprintf("[%s] Sending %s request to hub %s:%d...", __METHOD__, $connector->getConfigInstance()->readConfig("hub_peer_hello"), $address, $port )); // Get a HubPeer instance $peerInstance = HubPeer::createHubPeerBySocket($connector->getSocketResource(), $hubInstance); // Send a HELLO to the master hub $helloed = 0; $retries = 0; while (!$peerInstance->ifHelloReplied()) { // Within timeout? if ((time() - $helloed) >= $connector->getConfigInstance()->readConfig("hub_hello_timeout")) { // Send HELLOs out in periodic times $peerInstance->sendMessage($connector->getConfigInstance()->readConfig("hub_peer_hello")); $helloed = time(); $retries++; if ($retries == $connector->getConfigInstance()->readConfig("hub_hello_retires")) { // Maximum retries reached throw new HubHelloException( array( 'this' => $connector, 'peer' => $peerInstance ), HubCoreLoop::EXCEPTION_HELLO_TIMED_OUT ); } } // END - if } // END - while // Set the peer instance $connector->setPeerInstance($peerInstance); // Return the instance return $connector; } /** * Aquires a socket link to a specified IP address and port number. It * throws subclasses of SocketException-s if the peer is down or not * responding. If the connection is up it writes it's resource into * the attribute $socketResource and waits for incoming data packages. * * @param $address The peer's IP address * @param $port The peer's port number * @return void * @throws SocketCreationException If creation of the socket wents wrong * @throws SocketConnectException If the connection was not established */ public function aquireConnectionToAddress ($address, $port) { // Create a socket for binding to the address $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); // Was it a success? if (!is_resource($socket)) { // This fails! :( throw new SocketCreationException( array( 'this' => $this, 'code' => socket_last_error() ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM ); } // END - fi // Now connect to the peer if (@socket_connect($socket, $address, $port) === false) { // Something wents wrong! throw new SocketConnectException ( array( 'this' => $this, 'code' => socket_last_error() ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM ); } // END - if // Set non-blocking mode @socket_set_nonblock($socket); // Set the socket $this->socketResource = $socket; } /** * Getter for current socket * * @return $socketResource The current socket resource or null if not set */ public final function getSocketResource() { return $this->socketResource; } /** * Setter for a HubPeer instance * * @param $peerInstance An instance of a HubPeer class * @return void */ public final function setPeerInstance (HubPeer $peerInstance) { $this->peerInstance = $peerInstance; } /** * Handles any incoming master requests * * @return void */ public function handleMasterRequests () { // Just ask the peer instance $command = $this->peerInstance->handleMasterRequests(); } } // END - class ?>