]> git.mxchange.org Git - hub.git/blob - application/hub/main/class_HubConnector.php
72ee165278ed8dee19d1f16a8daf97884cf06241
[hub.git] / application / hub / main / class_HubConnector.php
1 <?php
2 /**
3  * A class for making socket connections to other hubs including the master hub
4  *
5  * @author              Roland Haeder <webmaster@ship-simu.org>
6  * @version             0.0
7  * @copyright   Copyright(c) 2007, 2008 Roland Haeder, this is free software
8  * @license             GNU GPL 3.0 or any newer version
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23 class HubConnector extends BaseFrameworkSystem {
24         /**
25          * The socket we shall use for communication
26          */
27         private $socketResource = null;
28
29         /**
30          * The peer instance (HubPeer class)
31          */
32         private $peerInstance = null;
33
34         /**
35          * The private constructor
36          *
37          * @return      void
38          */
39         protected function __construct () {
40                 // Call parent constructor
41                 parent::__construct(__CLASS__);
42
43                 // Set description
44                 $this->setObjectDescription("Hub-Connector");
45
46                 // Set unique ID
47                 $this->createUniqueID();
48
49                 // Tidy up a little
50                 $this->removeSystemArray();
51                 $this->removeNumberFormaters();
52         }
53
54         /**
55          * Creates an instance based on the (IP) address and port number of this
56          * class. Next it tries to connect to the specified peer and communicates
57          * to it over a socket
58          *
59          * @param               $address                                The peer's IP address
60          * @param               $port                           The peer's port number
61          * @param               $hubInstance                    An instance of a HubCoreLoop class
62          * @return      $connector                      An instance of this class
63          * @throws      HubHelloException               If HELLO retries reached maximum
64          */
65         public final static function createHubConnectorByAddressPort ($address, $port, HubCoreLoop $hubInstance) {
66                 // Get a new instance of this class
67                 $connector = new HubConnector();
68
69                 // Connect to the given address and IP number
70                 $connector->aquireConnectionToAddress($address, $port);
71
72                 // Message to console
73                 $hubInstance->getOutputInstance()->output(sprintf("[%s] Sending %s request to hub %s:%d...",
74                         __METHOD__,
75                         $connector->getConfigInstance()->readConfig("hub_peer_hello"),
76                         $address,
77                         $port
78                 ));
79
80                 // Get a HubPeer instance
81                 $peerInstance = HubPeer::createHubPeerBySocket($connector->getSocketResource(), $hubInstance);
82
83                 // Send a HELLO to the master hub
84                 $helloed = 0; $retries = 0;
85                 while (!$peerInstance->ifHelloReplied()) {
86                         // Within timeout?
87                         if ((time() - $helloed) >= $connector->getConfigInstance()->readConfig("hub_hello_timeout")) {
88                                 // Send HELLOs out in periodic times
89                                 $peerInstance->sendMessage($connector->getConfigInstance()->readConfig("hub_peer_hello"));
90                                 $helloed = time(); $retries++;
91                                 if ($retries == $connector->getConfigInstance()->readConfig("hub_hello_retires")) {
92                                         // Maximum retries reached
93                                         throw new HubHelloException(
94                                                 array(
95                                                         'this'  => $connector,
96                                                         'peer'  => $peerInstance
97                                                 ), HubCoreLoop::EXCEPTION_HELLO_TIMED_OUT
98                                         );
99                                 }
100                         } // END - if
101                 } // END - while
102
103                 // Set the peer instance
104                 $connector->setPeerInstance($peerInstance);
105
106                 // Return the instance
107                 return $connector;
108         }
109
110         /**
111          * Aquires a socket link to a specified IP address and port number. It
112          * throws subclasses of SocketException-s if the peer is down or not
113          * responding. If the connection is up it writes it's resource into
114          * the attribute $socketResource and waits for incoming data packages.
115          *
116          * @param               $address                                The peer's IP address
117          * @param               $port                           The peer's port number
118          * @return      void
119          * @throws      SocketCreationException If creation of the socket wents wrong
120          * @throws      SocketConnectException  If the connection was not established
121          */
122         public function aquireConnectionToAddress ($address, $port) {
123                 // Create a socket for binding to the address
124                 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
125
126                 // Was it a success?
127                 if (!is_resource($socket)) {
128                         // This fails! :(
129                         throw new SocketCreationException(
130                                 array(
131                                         'this' => $this,
132                                         'code' => socket_last_error()
133                                 ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM
134                         );
135                 } // END - fi
136
137                 // Now connect to the peer
138                 if (@socket_connect($socket, $address, $port) === false) {
139                         // Something wents wrong!
140                         throw new SocketConnectException (
141                                 array(
142                                         'this'  => $this,
143                                         'code'  => socket_last_error()
144                                 ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM
145                         );
146                 } // END - if
147
148                 // Set non-blocking mode
149                 @socket_set_nonblock($socket);
150
151                 // Set the socket
152                 $this->socketResource = $socket;
153         }
154
155         /**
156          * Getter for current socket
157          *
158          * @return      $socketResource The current socket resource or null if not set
159          */
160         public final function getSocketResource() {
161                 return $this->socketResource;
162         }
163
164         /**
165          * Setter for a HubPeer instance
166          *
167          * @param               $peerInstance           An instance of a HubPeer class
168          * @return      void
169          */
170         public final function setPeerInstance (HubPeer $peerInstance) {
171                 $this->peerInstance = $peerInstance;
172         }
173
174         /**
175          * Handles any incoming master requests
176          *
177          * @return      void
178          */
179         public function handleMasterRequests () {
180                 // Just ask the peer instance
181                 $command = $this->peerInstance->handleMasterRequests();
182         }
183
184 } // END - class
185 ?>