3 * A class for making socket connections to other hubs including the master hub
5 class HubConnector extends BaseFrameworkSystem {
7 * The socket we shall use for communication
9 private $socketResource = null;
12 * The peer instance (HubPeer class)
14 private $peerInstance = null;
17 * The private constructor
21 private function __construct () {
22 // Call parent constructor
23 parent::constructor(__CLASS__);
26 $this->setPartDescr("Hub-Connector");
29 $this->createUniqueID();
32 $this->removeSystemArray();
33 $this->removeNumberFormaters();
37 * Creates an instance based on the (IP) address and port number of this
38 * class. Next it tries to connect to the specified peer and communicates
41 * @param $address The peer's IP address
42 * @param $port The peer's port number
43 * @param $hubInstance An instance of a HubCoreLoop class
44 * @return $connector An instance of this class
45 * @throws HubHelloException If HELLO retries reached maximum
47 public final static function createHubConnectorByAddressPort ($address, $port, HubCoreLoop $hubInstance) {
48 // Get a new instance of this class
49 $connector = new HubConnector();
51 // Connect to the given address and IP number
52 $connector->aquireConnectionToAddress($address, $port);
55 $hubInstance->getOutputInstance()->output(sprintf("[%s] Sending %s request to hub %s:%d...",
57 $connector->getConfigInstance()->readConfig("hub_peer_hello"),
62 // Get a HubPeer instance
63 $peerInstance = HubPeer::createHubPeerBySocket($connector->getSocketResource(), $hubInstance);
65 // Send a HELLO to the master hub
66 $helloed = 0; $retries = 0;
67 while (!$peerInstance->ifHelloReplied()) {
69 if ((time() - $helloed) >= $connector->getConfigInstance()->readConfig("hub_hello_timeout")) {
70 // Send HELLOs out in periodic times
71 $peerInstance->sendMessage($connector->getConfigInstance()->readConfig("hub_peer_hello"));
72 $helloed = time(); $retries++;
73 if ($retries == $connector->getConfigInstance()->readConfig("hub_hello_retires")) {
74 // Maximum retries reached
75 throw new HubHelloException(
78 'peer' => $peerInstance
79 ), HubCoreLoop::EXCEPTION_HELLO_TIMED_OUT
85 // Set the peer instance
86 $connector->setPeerInstance($peerInstance);
88 // Return the instance
93 * Aquires a socket link to a specified IP address and port number. It
94 * throws subclasses of SocketException-s if the peer is down or not
95 * responding. If the connection is up it writes it's resource into
96 * the attribute $socketResource and waits for incoming data packages.
98 * @param $address The peer's IP address
99 * @param $port The peer's port number
101 * @throws SocketCreationException If creation of the socket wents wrong
102 * @throws SocketConnectException If the connection was not established
104 public function aquireConnectionToAddress ($address, $port) {
105 // Create a socket for binding to the address
106 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
109 if (!is_resource($socket)) {
111 throw new SocketCreationException(
114 'code' => socket_last_error()
115 ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM
119 // Now connect to the peer
120 if (@socket_connect($socket, $address, $port) === false) {
121 // Something wents wrong!
122 throw new SocketConnectException (
125 'code' => socket_last_error()
126 ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM
130 // Set non-blocking mode
131 @socket_set_nonblock($socket);
134 $this->socketResource = $socket;
138 * Getter for current socket
140 * @return $socketResource The current socket resource or null if not set
142 public final function getSocketResource() {
143 return $this->socketResource;
147 * Setter for a HubPeer instance
149 * @param $peerInstance An instance of a HubPeer class
152 public final function setPeerInstance (HubPeer $peerInstance) {
153 $this->peerInstance = $peerInstance;
157 * Handles any incoming master requests
161 public function handleMasterRequests () {
162 // Just ask the peer instance
163 $command = $this->peerInstance->handleMasterRequests();