use CoreFramework\Visitor\Visitable;
use CoreFramework\Visitor\Visitor;
+// Import SPL stuff
+use \BadMethodCallException;
+
/**
* A Socket Container class
*
* support socket_getpeername():
* http://de2.php.net/manual/en/function.socket-getpeername.php#35656
*/
- if ($this->getSocketProtocol() == 'udp') {
+ if ($this->getSocketProtocol() == StorableSocket::SOCKET_PROTOCOL_UDP) {
// UDP is WIP:
$this->partialStub('UDP sockets are unfinished.');
} else {
}
/**
- * Creates a listening socket instance from given listener instance
+ * Creates a listening TCP socket instance from given listener instance
*
* @param $listenerInstance An instance of a Listenable class
* @return $socketInstance An instance of a StorableSocket class
return $socketInstance;
}
+ /**
+ * Creates a "listening" UDP socket instance from given listener instance
+ *
+ * @param $listenerInstance An instance of a Listenable class
+ * @return $socketInstance An instance of a StorableSocket class
+ * @throws InvalidSocketException Thrown if the socket could not be initialized
+ */
+ public static function createListenUdpSocket (Listenable $listenerInstance) {
+ // Create a streaming socket, of type TCP/IP
+ $socketResource = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
+
+ // Init fake package data with address/port from listener
+ $packageData = array(
+ StorableSocket::SOCKET_ARRAY_INDEX_ADDRESS => $listenerInstance->getListenAddress(),
+ StorableSocket::SOCKET_ARRAY_INDEX_PORT => $listenerInstance->getListenPort(),
+ );
+
+ // Create socket instance
+ $socketInstance = self::createObjectByConfiguredName('socket_container_class', array($socketResource, StorableSocket::SOCKET_PROTOCOL_UDP, $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
+
+ // Check if there was an error else
+ if ($socketInstance->getLastSocketErrorCode() > 0) {
+ // Handle this socket error with a faked recipientData array
+ $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+ } // END - if
+
+ // Set the option to reuse the port
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: Enabling re-use address ...');
+ if (!$socketInstance->enableSocketReuseAddress()) {
+ // Handle this socket error with a faked recipientData array
+ $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+ } // END - if
+
+ /*
+ * "Bind" the socket to the given address, on given port so this means
+ * that all connections on this port are now our resposibility to
+ * send/recv data, disconnect, etc..
+ */
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: Binding to address ' . $listenerInstance->getListenAddress() . ':' . $listenerInstance->getListenPort());
+ if (!$socketInstance->bindSocketTo($listenerInstance->getListenAddress(), $listenerInstance->getListenPort())) {
+ // Handle this socket error with a faked recipientData array
+ $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+ } // END - if
+
+ // Now, we want non-blocking mode
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: Setting non-blocking mode.');
+ 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 prepepared socket
+ return $socketInstance;
+ }
+
}
namespace Hub\Listener\Udp;
// Import application-specific stuff
+use Hub\Container\Socket\StorableSocket;
+use Hub\Factory\Socket\SocketFactory;
use Hub\Listener\BaseListener;
use Hub\Listener\Listenable;
parent::__construct(__CLASS__);
// Set the protocol to UDP
- $this->setProtocolName('udp');
+ $this->setProtocolName(StorableSocket::SOCKET_PROTOCOL_UDP);
}
/**
* Initializes the listener by setting up the required socket server
*
* @return void
- * @throws InvalidSocketException Thrown if the socket is invalid or an error was detected.
- * @todo Needs rewrite!
*/
public function initListener () {
- // Try to open a UDP socket
- $mainSocket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
-
- // Is the socket a valid resource or do we have any error?
- if (!is_resource($mainSocket)) {
- // Then throw an InvalidSocketException
- throw new InvalidSocketException(array($this, $mainSocket), self::EXCEPTION_INVALID_SOCKET);
- } // END - if
-
- /*
- * "Bind" the socket to the given address, on given port so this means
- * that all connections on this port are now our resposibility to
- * send/recv data, disconnect, etc..
- */
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('UDP-LISTENER: Binding to address ' . $this->getListenAddress() . ':' . $this->getListenPort());
- if (!socket_bind($mainSocket, $this->getListenAddress(), $this->getListenPort())) {
- // Handle the socket error with a faked recipientData array
- $this->handleSocketError(__METHOD__, __LINE__, $mainSocket, array('0.0.0.0', '0'));
- } // END - if
-
- // Now, we want non-blocking mode
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('UDP-LISTENER: Setting non-blocking mode.');
- if (!socket_set_nonblock($mainSocket)) {
- // Handle the socket error with a faked recipientData array
- $this->handleSocketError(__METHOD__, __LINE__, $mainSocket, array('0.0.0.0', '0'));
- } // END - if
-
- // Set the option to reuse the port
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('UDP-LISTENER: Setting re-use address option.');
- if (!socket_set_option($mainSocket, SOL_SOCKET, SO_REUSEADDR, 1)) {
- // Handle the socket error with a faked recipientData array
- $this->handleSocketError(__METHOD__, __LINE__, $mainSocket, array('0.0.0.0', '0'));
- } // END - if
+ // Get socket instance
+ $socketInstance = SocketFactory::createListenUdpSocket($this);
// Remember the socket in our class
- $this->registerServerSocketInstance($mainSocket);
+ $this->registerServerSocketInstance($socketInstance);
// Initialize the network package handler
$handlerInstance = ObjectFactory::createObjectByConfiguredName('udp_raw_data_handler_class');
use Hub\Database\Frontend\Node\Information\NodeInformationDatabaseWrapper;
use Hub\Generic\BaseHubSystem;
+// Import SPL stuff
+use \BadMethodCallException;
+
/**
* A class for UNLs (Universal Node Locator)
*