application/hub/interfaces/query/class_Queryable.php -text
application/hub/interfaces/queues/.htaccess -text
application/hub/interfaces/queues/class_Queueable.php -text
+application/hub/interfaces/socket/.htaccess -text
application/hub/interfaces/states/.htaccess -text
application/hub/interfaces/states/class_ -text
application/hub/interfaces/states/class_Stateable.php -text
application/hub/main/handler/tasks/.htaccess -text
application/hub/main/handler/tasks/class_TaskHandler.php -text
application/hub/main/helper/.htaccess -text
+application/hub/main/helper/connection/.htaccess -text
+application/hub/main/helper/connection/tcp/.htaccess -text
+application/hub/main/helper/connection/udp/.htaccess -text
application/hub/main/helper/hub/.htaccess -text
application/hub/main/helper/hub/announcement/.htaccess -text
application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php -text
application/hub/main/helper/hub/class_ -text
application/hub/main/helper/hub/class_BaseHubHelper.php -text
+application/hub/main/helper/hub/connection/.htaccess -text
application/hub/main/iterator/.htaccess -text
application/hub/main/iterator/class_ -text
application/hub/main/iterator/class_BaseIterator.php -text
application/hub/main/queues/peer/class_LocalPeerQueue.php -text
application/hub/main/registry/.htaccess -text
application/hub/main/registry/objects/.htaccess -text
+application/hub/main/registry/socket/.htaccess -text
application/hub/main/resolver/.htaccess -text
application/hub/main/resolver/command/.htaccess -text
application/hub/main/resolver/command/console/.htaccess -text
application/hub/main/template/announcement/.htaccess -text
application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php -text
application/hub/main/template/objects/.htaccess -text
+application/hub/main/tools/.htaccess -text
application/hub/main/visitor/.htaccess -text
application/hub/main/visitor/class_ -text
application/hub/main/visitor/class_BaseVisitor.php -text
// CFG: HUB-ANNOUNCEMENT-HELPER-CLASS
$cfg->setConfigEntry('hub_announcement_helper_class', 'HubDescriptorHelper');
+// CFG: HUB-SELF-CONNECT-HELPER-CLASS
+$cfg->setConfigEntry('hub_self_connect_helper_class', 'HubSelfConnectHelper');
+
// CFG: DEFAULT-CONSOLE-COMMAND
$cfg->setConfigEntry('default_console_command', 'main');
// CFG: STACKER-DECLARED-MAX-SIZE
$cfg->setConfigEntry('stacker_declared_max_size', 1000);
+// CFG: STACKER-OUTGOING-MAX-SIZE
+$cfg->setConfigEntry('stacker_outgoing_max_size', 100);
+
// CFG: STACKER-OBJECT-REGISTRY-MAX-SIZE
$cfg->setConfigEntry('stacker_object_registry_max_size', 100);
// CFG: PACKAGE-TAGS-CLASS
$cfg->setConfigEntry('package_tags_class', 'PackageTags');
+// CFG: TCP-CONNECTION-CLASS
+$cfg->setConfigEntry('tcp_connection_class', 'TcpConnectionHelper');
+
+// CFG: UDP-CONNECTION-CLASS
+$cfg->setConfigEntry('udp_connection_class', 'UdpConnectionHelper');
+
+// CFG: TCP-BUFFER-LENGTH
+$cfg->setConfigEntry('tcp_buffer_length', 1024);
+
+// CFG: UDP-BUFFER-LENGTH
+$cfg->setConfigEntry('udp_buffer_length', 1024);
+
// [EOF]
?>
* matching socket resource.
*
* @param $packageData Raw package data array
+ * @param $packageInstance A Deliverable instance
* @return $socketResource A valid socket resource
*/
function discoverSocket (array $packageData);
* @throws HubAlreadyAnnouncedException If this hub is already announced
*/
function announceSelfToUpperNodes (Taskable $taskInstance);
+
+ /**
+ * Does a self-connect attempt on the public IP address. This should make
+ * it sure, we are reachable from outside world.
+ *
+ * @param $taskInstance The task instance running this announcement
+ * @return void
+ */
+ function doSelfConnection (Taskable $taskInstance);
}
// [EOF]
interface Deliverable extends FrameworkInterface {
/**
* "Enqueues" raw content into this delivery class by reading the raw content
- * from given template instance.
+ * from given template instance and pushing it on the 'undeclared' stack.
*
* @param $helperInstance A BaseHubHelper instance
* @return void
*/
function isPackageEnqueued ();
+ /**
+ * Checks wether a package has been declared
+ *
+ * @return $isDeclared Wether a package is declared
+ */
+ function isPackageDeclared ();
+
+ /**
+ * Checks wether a package should be sent out
+ *
+ * @return $isWaitingDelivery Wether a package is waiting for delivery
+ */
+ function isPackageWaitingDelivery ();
+
/**
* Delivers an enqueued package to the stated destination. If a non-session
* id is provided, recipient resolver is being asked (and instanced once).
*/
function declareEnqueuedPackage ();
- /**
- * Checks wether a package has been declared
- *
- * @return $isDeclared Wether a package is declared
- */
- function isPackageDeclared ();
-
/**
* Delivers the next declared package. Only one package per time will be sent
* because this may take time and slows down the whole delivery
* @return void
*/
function deliverDeclaredPackage ();
+
+ /**
+ * Sends waiting packages out for delivery
+ *
+ * @return void
+ */
+ function sentWaitingPackage ();
}
// [EOF]
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-interface PoolablePeer extends Poolable {
+interface PoolablePeer extends Poolable, SocketTag {
/**
* Adds a socket resource to the peer pool
*
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * An interface/tag for socket classes
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+interface SocketTag extends FrameworkInterface {
+ /**
+ * "Getter" for a valid socket resource from given packae data.
+ *
+ * @param $packageData Raw package data
+ * @return $socketResource Socket resource
+ */
+ function getSocketFromPackageData (array $packageData);
+}
+
+// [EOF]
+?>
*/
private $listenerInstance = null;
+ /**
+ * A network package handler instance
+ */
+ private $packageInstance = null;
+
/**
* Protected constructor
*
public final function getNodeInstance () {
return $this->nodeInstance;
}
+
+ /**
+ * Setter for network package handler instance
+ *
+ * @param $packageInstance The network package handler instance we shall set
+ * @return void
+ */
+ protected final function setPackageInstance (Networkable $packageInstance) {
+ $this->packageInstance = $packageInstance;
+ }
+
+ /**
+ * Getter for network package handler instance
+ *
+ * @return $packageInstance The network package handler instance we shall set
+ */
+ protected final function getPackageInstance () {
+ return $this->packageInstance;
+ }
}
// [EOF]
return $discoveryInstance;
}
+ /**
+ * Tries to dicover the right listener instance
+ *
+ * @param $protocolName Protocol name
+ * @param $packageData Raw package data
+ * @return $listenerInstance An instance of a Listenable instance or null
+ */
+ public function discoverListenerInstance ($protocolName, array $packageData) {
+ /*
+ * Get the listener pool instance, we need to lookup the matching
+ * listener->poolInstance chain there.
+ */
+ $poolInstance = Registry::getRegistry()->getInstance('node')->getListenerPoolInstance();
+
+ // Init listener instance
+ $listenerInstance = null;
+
+ /*
+ * Now we need to choose again. It is wether we are speaking with a hub
+ * or with a client. So just handle it over to all listeners in this
+ * pool.
+ */
+ foreach ($poolInstance->getPoolEntriesInstance()->getArrayFromGroup($protocolName) as $listenerInstance) {
+ // Does the listener want that package?
+ if ($listenerInstance->ifListenerAcceptsPackageData($packageData)) {
+ // This listener likes our package data, so abort here
+ break;
+ } // END - if
+ } // END - foreach
+
+ // Return it
+ return $listenerInstance;
+ }
+
/**
* Tries to discover the right socket for given package data and returns a
* matching socket resource for that protocol.
*/
$protocolName = $tagsInstance->chooseProtocolFromPackageData($packageData);
- /*
- * Get the listener pool instance, we need to lookup the matching
- * listener->poolInstance chain there.
- */
- $poolInstance = Registry::getRegistry()->getInstance('node')->getListenerPoolInstance();
+ // Get the listener instance
+ $listenerInstance = $this->discoverListenerInstance($protocolName, $packageData);
- // So get the pool entries list first
- $poolEntriesInstance = $poolInstance->getPoolEntriesInstance();
+ // If there is no listener who wants to have that package, we simply drop it here
+ if (is_null($listenerInstance)) {
+ // @TODO We may need some locking here
+ // Abort with no resource
+ return false;
+ } // END - if
/*
- * Now we need to choose again. It is wether we are speaking with a hub
- * or with a client. So just handle it over to all listeners in that
- * pool.
+ * Now we have the listener instance, we can determine the right
+ * resource to continue. The first step is to get the attached pool
+ * instance and pass over the whole package data to get the right
+ * socket.
*/
- foreach ($poolEntriesInstance->getArrayFromGroup($protocolName) as $listenerInstance) {
- // Does the listener want that package?
- if ($listenerInstance->ifListenerAcceptsPackageData($packageData)) {
- // This listener likes our package data!
- die(print_r($listenerInstance, true));
- break;
- } // END - if
- } // END - foreach
- die();
+ $socketResource = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData);
+
+ // Is it false, the recipient isn't known to us and we have no connection to it
+ if (!is_resource($socketResource)) {
+ // Create a new socket resource
+ $socketResource = HubConnectionHelper::getSocketFromPackageData($packageData, $protocolName);
+ } // END - if
// And return it
return $socketResource;
$this->debugOutput('HANDLER: Handling TCP package from peer ' . $resource);
// Read the raw data from socket
- $rawData = socket_read($resource, 1500, PHP_NORMAL_READ);
+ $rawData = socket_read($resource, $this->getConfigInstance()->getConfigEntry('tcp_buffer_length'), PHP_NORMAL_READ);
// Is it valid?
if (($rawData === false) || (socket_last_error($resource) > 0)) {
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A general ConnectionHelper class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+class BaseConnectionHelper extends BaseHubHelper implements Registerable, ProtocolHandler {
+ /**
+ * Protocol used
+ */
+ private $protocol = 'invalid';
+
+ /**
+ * Port number used
+ */
+ private $port = 0;
+
+ /**
+ * (IP) Adress used
+ */
+ private $address = 0;
+
+ /**
+ * Sent data in bytes
+ */
+ private $sentData = 0;
+
+ /**
+ * Offset
+ */
+ private $offset = 0;
+
+ /**
+ * Protected constructor
+ *
+ * @param $className Name of the class
+ * @return void
+ */
+ protected function __construct ($className) {
+ // Call parent constructor
+ parent::__construct($className);
+
+ // Register this connection helper
+ Registry::getRegistry()->addInstance('connection', $this);
+ }
+
+ /**
+ * Getter for port number to satify ProtocolHandler
+ *
+ * @return $port The port number
+ */
+ public final function getPort () {
+ return $this->port;
+ }
+
+ /**
+ * Setter for port number to satify ProtocolHandler
+ *
+ * @param $port The port number
+ * @return void
+ */
+ protected final function setPort ($port) {
+ $this->port = $port;
+ }
+
+ /**
+ * Getter for protocol
+ *
+ * @return $protocol Used protocol
+ */
+ public final function getProtocol () {
+ return $this->protocol;
+ }
+
+ /**
+ * Setter for protocol
+ *
+ * @param $protocol Used protocol
+ * @return void
+ */
+ protected final function setProtocol ($protocol) {
+ $this->protocol = $protocol;
+ }
+
+ /**
+ * Getter for IP address
+ *
+ * @return $address The IP address
+ */
+ public final function getAddress () {
+ return $this->address;
+ }
+
+ /**
+ * Setter for IP address
+ *
+ * @param $address The IP address
+ * @return void
+ */
+ protected final function setAddress ($address) {
+ $this->address = $address;
+ }
+
+ /**
+ * Sends raw package data to the recipient
+ *
+ * @param $packageData Raw package data
+ * @return void
+ *@ throws InvalidSocketException If we got a problem with this socket
+ */
+ public function sendRawPackageData (array $packageData) {
+ // We need to "package" all data. This is done by a implode()
+ $rawData = implode(NetworkPackage::PACKAGE_DATA_SEPERATOR, $packageData);
+
+ // Get socket resource
+ $socketResource = $this->getSocketResource();
+
+ // And deliver it
+ $numBytes = @socket_write($socketResource, $rawData, $this->getConfigInstance()->getConfigEntry($this->getProtocol() . '_buffer_length') - $this->offset);
+
+ // If there was an error, we don't continue here
+ if ($numBytes === false) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // And throw it
+ throw new InvalidSocketException(array($this, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ // How much has been sent?
+ die('num='.$numBytes."\n");
+ }
+
+ /**
+ * Getter for real class name
+ *
+ * @return $class Name of this class
+ */
+ public function __toString () {
+ // Class name representation
+ $class = $this->getAddress() . ':' . $this->getPort() . ':' . parent::__toString();
+
+ // Return it
+ return $class;
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A TCP connection helper class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ * @todo Find an interface for hub helper
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+class TcpConnectionHelper extends BaseConnectionHelper {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set protocol
+ $this->setProtocol('tcp');
+ }
+
+ /**
+ * Creates a socket resource ("connection") for given recipient in package data
+ *
+ * @param $packageData Raw package data
+ * @return $socketResource Socket resource
+ * @throws InvalidSocketException If the socket is invalid
+ */
+ public static function createConnectionFromPackageData (array $packageData) {
+ // Create an instance
+ $helperInstance = new TcpConnectionHelper();
+
+ // Create a socket instance
+ $socketResource = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+
+ // Is the socket resource valid?
+ if (!is_resource($socketResource)) {
+ // Something bad happened
+ throw new InvalidSocketException(array($helperInstance, gettype($socketResource), 0, 'invalid'), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Check if there was an error else
+ if ($socketError > 0) {
+ // Then throw again
+ throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, socket_strerror($socketError)), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ // Set the option to reuse the port
+ if (!socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1)) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $helperInstance->shutdownSocket($socketResource);
+
+ // And throw again
+ throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ // Now, we want non-blocking mode
+ if (!socket_set_nonblock($socketResource)) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $helperInstance->shutdownSocket($socketResource);
+
+ // And throw again
+ throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ // Set the resource
+ $helperInstance->setSocketResource($socketResource);
+
+ // Resolve any session ids; 0 = IP, 1 = Port
+ $recipientData = explode(':', HubTools::resolveSessionId($packageData['recipient']));
+
+ // Set ip/port
+ $helperInstance->setAddress($recipientData[0]);
+ $helperInstance->setPort($recipientData[1]);
+
+ // Debug message
+ $helperInstance->debugOutput('CONNECTION: Connecting to ' . $recipientData[0] . ':' . $recipientData[1]);
+
+ // Now connect to it
+ if (!@socket_connect($socketResource, $recipientData[0], $recipientData[1])) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // And throw again, but not for 'Operation now in progress', we should wait a little
+ if ($socketError != 115) {
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $helperInstance->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } else {
+ // Debug output
+ $helperInstance->debugOutput('CONNECTION: Operation is in progress, maybe recipient is down?');
+ }
+ } // END - if
+
+ // Okay, that should be it. So return it...
+ return $socketResource;
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A UDP connection helper class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ * @todo Find an interface for hub helper
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+class UdpConnectionHelper extends BaseConnectionHelper {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set protocol
+ $this->setProtocol('udp');
+ }
+
+ /**
+ * Creates a socket resource ("connection") for given recipient in package data
+ *
+ * @param $packageData Raw package data
+ * @return $socketResource Socket resource
+ */
+ public static function createConnectionFromPackageData (array $packageData) {
+ die();
+ }
+}
+
+// [EOF]
+?>
// Return the prepared instance
return $helperInstance;
}
-
- /**
- * "Getter" for package tags in a simple array
- *
- * @return $tags An array with all tags for the currently handled package
- */
}
// [EOF]
<?php
/**
- * A general hub helper class
+ * A general hub helper class. This class does not extend BaseHelper.
*
* @author Roland Haeder <webmaster@ship-simu.org>
* @version 0.0.0
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-class BaseHubHelper extends BaseHelper {
- /**
- * An instance of a node
- */
- private $nodeInstance = null;
-
+class BaseHubHelper extends BaseHubSystem {
/**
* Protected constructor
*
// Call parent constructor
parent::__construct($className);
}
-
- /**
- * Setter for node instance
- *
- * @param $nodeInstance An instance of a node node
- * @return void
- */
- protected final function setNodeInstance (NodeHelper $nodeInstance) {
- $this->nodeInstance = $nodeInstance;
- }
-
- /**
- * Getter for node instance
- *
- * @return $nodeInstance An instance of a node node
- */
- public final function getNodeInstance () {
- return $this->nodeInstance;
- }
}
// [EOF]
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A Connection hub helper class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ * @todo Find an interface for hub helper
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+class HubConnectionHelper extends BaseHubHelper {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * "Getter" for a valid socket resource from given packae data.
+ *
+ * @param $packageData Raw package data
+ * @param $protocolName Protocol name (TCP/UDP)
+ * @return $socketResource Socket resource
+ */
+ public static function getSocketFromPackageData (array $packageData, $protocolName) {
+ // Construct configuration entry for object factory
+ $configEntry = $protocolName . '_connection_class';
+
+ // And call the static method
+ $socketResource = call_user_func(FrameworkConfiguration::getInstance()->getConfigEntry($configEntry) . '::createConnectionFromPackageData', $packageData);
+
+ // Return the resource
+ return $socketResource;
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+<?php
+/**
+ * A SelfConnect hub helper class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ * @todo Find an interface for hub helper
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+class HubSelfConnectHelper extends BaseHubHelper {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Creates the helper class
+ *
+ * @return $helperInstance A prepared instance of this helper
+ */
+ public final static function createHubSelfConnectHelper () {
+ // Get new instance
+ $helperInstance = new HubSelfConnectHelper();
+
+ // Return the prepared instance
+ return $helperInstance;
+ }
+
+ /**
+ * Do the self-connect attempt by delivering a package to ourselfs
+ *
+ * @return void
+ */
+ public function doSelfConnect () {
+ $this->partialStub('Not yet finished.');
+ }
+}
+
+// [EOF]
+?>
*/
private $poolInstance = null;
- /**
- * A network package handler instance
- */
- private $packageInstance = null;
-
/**
* Protected constructor
*
* @param $poolInstance The peer pool instance we shall set
* @return void
*/
- protected final function setPoolInstance (Poolablepeer $poolInstance) {
+ protected final function setPoolInstance (PoolablePeer $poolInstance) {
$this->poolInstance = $poolInstance;
}
return $this->poolInstance;
}
- /**
- * Setter for network package handler instance
- *
- * @param $packageInstance The network package handler instance we shall set
- * @return void
- */
- protected final function setPackageInstance (Networkable $packageInstance) {
- $this->packageInstance = $packageInstance;
- }
-
- /**
- * Getter for network package handler instance
- *
- * @return $packageInstance The network package handler instance we shall set
- */
- protected final function getPackageInstance () {
- return $this->packageInstance;
- }
-
/**
* Registeres the given socket resource for "this" listener instance. This
* will be done in a seperate class to allow package writers to use it
protected final function setListenerType ($listenerType) {
$this->listenerType = $listenerType;
}
+
+ /**
+ * Getter for peer pool instance
+ *
+ * @return $poolInstance The peer pool instance we shall set
+ */
+ public final function getPoolInstance () {
+ return $this->getListenerInstance()->getPoolInstance();
+ }
}
// [EOF]
/**
* Announces this hub to the upper (bootstrap or list) hubs. After this is
- * successfully done the given task is unregistered from the handler.
+ * successfully done the given task is unregistered from the handler. This
+ * might look a bit overloaded here but the announcement phase isn't a
+ * simple "Hello there" message, it may later on also contain more
+ * informations like the object list.
*
* @param $taskInstance The task instance running this announcement
* @return void
} // END - if
// Debug output
- $this->debugOutput('HUB: Self-announcement: START (taskInstance=' . $taskInstance->__toString(). ')');
+ $this->debugOutput('HUB: Self Announcement: START (taskInstance=' . $taskInstance->__toString(). ')');
// Get a helper instance
$helperInstance = ObjectFactory::createObjectByConfiguredName('hub_announcement_helper_class', array($this));
$this->getStateInstance()->nodeAnnouncedToUpperHubs();
// Debug output
- $this->debugOutput('HUB: Self-announcement: FINISHED');
+ $this->debugOutput('HUB: Self Announcement: FINISHED');
+ }
+
+ /**
+ * Does a self-connect attempt on the public IP address. This should make
+ * it sure, we are reachable from outside world. For this kind of package we
+ * don't need that overload we have in the announcement phase.
+ *
+ * @param $taskInstance The task instance running this announcement
+ * @return void
+ */
+ public function doSelfConnection (Taskable $taskInstance) {
+ // Debug output
+ $this->debugOutput('HUB: Self Connection: START (taskInstance=' . $taskInstance->__toString(). ')');
+
+ // Get a helper instance
+ $helperInstance = ObjectFactory::createObjectByConfiguredName('hub_self_connect_helper_class', array($this));
+
+ // And send the package away
+ $helperInstance->doSelfConnect();
+
+ // Debug output
+ $this->debugOutput('HUB: Self Connection: FINISHED');
}
/**
*/
const PACKAGE_TAGS_SEPERATOR = ';';
+ /**
+ * Raw package data seperator
+ */
+ const PACKAGE_DATA_SEPERATOR = '|';
+
/**
* Stacker name for "undeclared" packages
*/
*/
const STACKER_NAME_DECLARED = 'declared';
+ /**
+ * Stacker name for "out-going" packages
+ */
+ const STACKER_NAME_OUTGOING = 'outgoing';
+
/**
* Network target (alias): 'upper hubs'
*/
// Now discover the right protocol
$socketResource = $discoveryInstance->discoverSocket($packageData);
- die($socketResource);
+
+ // We have to put this socket in our registry, so get an instance
+ $registryInstance = SocketRegistry::createSocketRegistry();
+
+ // Get the listener from registry
+ $connectionInstance = Registry::getRegistry()->getInstance('connection');
+
+ // Is it not there?
+ if (!$registryInstance->isSocketRegistered($connectionInstance, $socketResource)) {
+ // Then register it
+ $registryInstance->registerSocket($connectionInstance, $socketResource, $packageData);
+ } // END - if
+
+ // We enqueue it again, but now in the out-going queue
+ $this->getStackerInstance()->pushNamed(self::STACKER_NAME_OUTGOING, $packageData);
+ }
+
+ /**
+ * Sends waiting packages
+ *
+ * @param $packageData Raw package data
+ * @return void
+ */
+ private function sendOutgoingPackage (array $packageData) {
+ // Get the right connection instance
+ $connectionInstance = SocketRegistry::createSocketRegistry()->getHandlerInstanceFromPackageData($packageData);
+
+ // Sent it away (we catch exceptions one method above
+ $connectionInstance->sendRawPackageData($packageData);
}
/**
return $isDeclared;
}
+ /**
+ * Checks wether a package should be sent out
+ *
+ * @return $isWaitingDelivery Wether a package is waiting for delivery
+ */
+ public function isPackageWaitingDelivery () {
+ // Check wether the stacker is not empty
+ $isWaitingDelivery = (($this->getStackerInstance()->isStackInitialized(self::STACKER_NAME_OUTGOING)) && (!$this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_OUTGOING)));
+
+ // Return the result
+ return $isWaitingDelivery;
+ }
+
/**
* Delivers an enqueued package to the stated destination. If a non-session
* id is provided, recipient resolver is being asked (and instanced once).
// And remove it finally
$this->getStackerInstance()->popNamed(self::STACKER_NAME_DECLARED);
}
+
+ /**
+ * Sends waiting packages out for delivery
+ *
+ * @return void
+ */
+ public function sentWaitingPackage () {
+ // Sanity check if we have packages waiting for delivery
+ if (!$this->isPackageWaitingDelivery()) {
+ // This is not fatal but should be avoided
+ // @TODO Add some logging here
+ return;
+ } // END - if
+
+ // Get the package again
+ $packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_OUTGOING);
+
+ // Now try to send it
+ try {
+ $this->sendOutgoingPackage($packageData);
+
+ // And remove it finally when it has been fully delivered
+ $this->getStackerInstance()->popNamed(self::STACKER_NAME_OUTGOING);
+ } catch (InvalidSocketException $e) {
+ // Output exception message
+ $this->debugOutput('PACKAGE: Package was not delivered: ' . $e->getMessage());
+ }
+ }
}
// [EOF]
// Return it
return $sockets;
}
+
+ /**
+ * "Getter" for a valid socket resource from given packae data.
+ *
+ * @param $packageData Raw package data
+ * @return $socketResource Socket resource
+ */
+ public function getSocketFromPackageData (array $packageData) {
+ // Default is no socket
+ $socketResource = false;
+
+ // Get all sockets and check them, skip the server socket
+ foreach ($this->getAllSockets() as $socket) {
+ // Is this a server socket?
+ if ($socket === $this->getListenerInstance()->getSocketResource()) {
+ // Skip this
+ continue;
+ } // END - if
+
+ // @TODO Check for IP
+ die(__METHOD__.':'.print_r($packageData, true));
+ } // END - foreach
+
+ // Return the determined socket resource
+ return $socketResource;
+ }
}
-//
+// [EOF]
?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A Socket registry
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+class SocketRegistry extends BaseRegistry implements Register, RegisterableSocket {
+ // Exception constants
+ const SOCKET_NOT_REGISTERED = 0xd00;
+
+ /**
+ * Instance of this class
+ */
+ private static $registryInstance = null;
+
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Creates a singleton instance of this registry class
+ *
+ * @return $registryInstance An instance of this class
+ */
+ public final static function createSocketRegistry () {
+ // Is an instance there?
+ if (is_null(self::$registryInstance)) {
+ // Not yet, so create one
+ self::$registryInstance = new SocketRegistry();
+ } // END - if
+
+ // Return the instance
+ return self::$registryInstance;
+ }
+
+ /**
+ * "Getter" to get a string respresentation for a key for the sub-registry
+ * in this format: class:protocol:port
+ *
+ * @param $protocolInstance An instance of a ProtocolHandler class
+ * @return $key A string representation of the socket for the registry
+ */
+ private function getSubRegistryKey (ProtocolHandler $protocolInstance) {
+ // Get protocol and port number and add both together
+ $key = sprintf("%s:%s:%s",
+ $protocolInstance->__toString(),
+ $protocolInstance->getProtocol(),
+ $protocolInstance->getPort()
+ );
+
+ // Return resulting key
+ return $key;
+ }
+
+ /**
+ * "Getter" to get a string respresentation of the protocol
+ *
+ * @param $protocolInstance An instance of a ProtocolHandler class
+ * @return $key A string representation of the protocol for the registry
+ */
+ private function getRegistryKeyFromProtocol (ProtocolHandler $protocolInstance) {
+ // Get the key
+ $key = $protocolInstance->getProtocol();
+
+ // Return resulting key
+ return $key;
+ }
+
+ /**
+ * Checks wether the given protocol is registered
+ *
+ * @param $protocolInstance An instance of a ProtocolHandler class
+ * @return $isRegistered Wether the protocol is registered
+ */
+ private function isProtocolRegistered (ProtocolHandler $protocolInstance) {
+ // Get the key
+ $key = $this->getRegistryKeyFromProtocol($protocolInstance);
+
+ // Determine it
+ $isRegistered = $this->instanceExists($key);
+
+ // Return result
+ return $isRegistered;
+ }
+
+ /**
+ * Checks wether given socket resource is registered. If $socketResource is
+ * false only the instance will be checked.
+ *
+ * @param $protocolInstance An instance of a ProtocolHandler class
+ * @param $socketResource A valid socket resource
+ * @return $isRegistered Wether the given socket resource is registered
+ */
+ public function isSocketRegistered (ProtocolHandler $protocolInstance, $socketResource) {
+ // Default is not registered
+ $isRegistered = false;
+
+ // First, check for the instance, there can be only once
+ if ($this->isProtocolRegistered($protocolInstance)) {
+ // That one is found so "get" a registry key from it
+ $key = $this->getRegistryKeyFromProtocol($protocolInstance);
+
+ // Get the registry
+ $registryInstance = $this->getInstance($key);
+
+ // "Get" a key for the socket
+ $socketKey = $this->getSubRegistryKey($protocolInstance);
+
+ // And simply ask it
+ $isRegistered = $registryInstance->instanceExists($socketKey);
+ } // END - if
+
+ // Return the result
+ return $isRegistered;
+ }
+
+ /**
+ * Registeres given socket for listener or throws an exception if it is already registered
+ *
+ * @param $protocolInstance An instance of a ProtocolHandler class
+ * @param $socketResource A valid socket resource
+ * @param $packageData Optional raw package data
+ * @throws SocketAlreadyRegisteredException If the given socket is already registered
+ * @return void
+ */
+ public function registerSocket (ProtocolHandler $protocolInstance, $socketResource, array $packageData = array()) {
+ // Is the socket already registered?
+ if ($this->isSocketRegistered($protocolInstance, $socketResource)) {
+ // Throw the exception
+ throw new SocketAlreadyRegisteredException($protocolInstance, BaseListener::EXCEPTION_SOCKET_ALREADY_REGISTERED);
+ } // END - if
+
+ // Does the instance exist?
+ if (!$this->isProtocolRegistered($protocolInstance)) {
+ // No, not found so we create a sub registry (not needed to configure!)
+ $registryInstance = SubRegistry::createSubRegistry();
+
+ // Now we can create the sub-registry for this protocol
+ $this->addInstance($this->getRegistryKeyFromProtocol($protocolInstance), $registryInstance);
+ } else {
+ // Get the sub-registry back
+ $registryInstance = $this->getInstance($this->getRegistryKeyFromProtocol($protocolInstance));
+ }
+
+ // Get a key for sub-registries
+ $socketKey = $this->getSubRegistryKey($protocolInstance);
+
+ // Get a socket container
+ $socketInstance = ObjectFactory::CreateObjectByConfiguredName('socket_container_class', array($socketResource, $protocolInstance, $packageData));
+
+ // We have a sub-registry, the socket key and the socket, now we need to put all together
+ $registryInstance->addInstance($socketKey, $socketInstance);
+ }
+
+ /**
+ * Getter for given listener's socket resource
+ *
+ * @param $protocolInstance An instance of a ProtocolHandler class
+ * @return $socketResource A valid socket resource
+ * @throws NoSocketRegisteredException If the requested socket is not registered
+ */
+ public function getRegisteredSocketResource (ProtocolHandler $protocolInstance) {
+ // The socket must be registered before we can return it
+ if (!$this->isSocketRegistered($protocolInstance, false)) {
+ // Throw the exception
+ throw new NoSocketRegisteredException ($protocolInstance, self::SOCKET_NOT_REGISTERED);
+ } // END - if
+
+ // Now get the key from the protocol
+ $key = $this->getRegistryKeyFromProtocol($protocolInstance);
+
+ // And get the registry
+ $registryInstance = $this->getInstance($key);
+
+ // Get a socket key
+ $socketKey = $this->getSubRegistryKey($protocolInstance);
+
+ // And the final socket resource
+ $socketResource = $registryInstance->getInstance($socketKey)->getSocketResource();
+
+ // Return the resource
+ return $socketResource;
+ }
+
+ /**
+ * "Getter" for protocol/connection instance from given package data
+ *
+ * @param $packageData Raw package data
+ * @return $protocolInstance An instance of a ProtocolHandler class
+ */
+ public function getHandlerInstanceFromPackageData (array $packageData) {
+ // Init protocol instance
+ $protocolInstance = null;
+
+ // Get all keys and check them
+ foreach ($this->getInstanceRegistry() as $key=>$registryInstance) {
+ // This is always a SubRegistry instance
+ foreach ($registryInstance->getInstanceRegistry() as $subKey=>$containerInstance) {
+ // This is a SocketContainer instance, so does the recipient match?
+ if ($containerInstance->ifAddressMatches($packageData['recipient'])) {
+ // Found one, so get the protocol instance and abort
+ $protocolInstance = $containerInstance->getProtocolInstance();
+ break;
+ } // END - if
+ } // END - foreach
+ } // END - foreach
+
+ // Return the protocol instance
+ return $protocolInstance;
+ }
+}
+
+// [EOF]
+?>
* @return void
*/
public function executeTask () {
- $this->partialStub('Unimplemented task.');
+ // Get the node instance and try it
+ Registry::getRegistry()->getInstance('node')->doSelfConnection($this);
}
}
// Okay, then deliver (better discover its recipients) this package
$packageInstance->declareEnqueuedPackage();
} elseif ($packageInstance->isPackageDeclared()) {
- // Finally deliver a package
+ // Prepare package for delivery
$packageInstance->deliverDeclaredPackage();
+ } elseif ($packageInstance->isPackageWaitingDelivery()) {
+ // Sent it finally out
+ $packageInstance->sentWaitingPackage();
}
}
}
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * This class contains static helper functions for our hub
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+class HubTools extends BaseFrameworkSystem {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Resolves given session id into a ip:port string, if ip:port is set, it won't be translated
+ *
+ * @param $sessionId Session id or ip:port string
+ * @return $recipient Recipient as ip:port string
+ */
+ public static function resolveSessionId ($sessionId) {
+ // Default is direct ip:port
+ $recipient = $sessionId;
+
+ // Does it match a direct ip:port? (hint: see www.regexlib.com for the regular expression)
+ if (!preg_match('/((?:2[0-5]{2}|1\d{2}|[1-9]\d|[1-9])\.(?:(?:2[0-5]{2}|1\d{2}|[1-9]\d|\d)\.){2}(?:2[0-5]{2}|1\d{2}|[1-9]\d|\d)):(\d|[1-9]\d|[1-9]\d{2,3}|[1-5]\d{4}|6[0-4]\d{3}|654\d{2}|655[0-2]\d|6553[0-5])/', $sessionId)) {
+ die(__METHOD__.': sessionId=' . $sessionId . "\n");
+ } // END - if
+
+ // Return it
+ return $recipient;
+ }
+}
+
+// [EOF]
+?>