]> git.mxchange.org Git - hub.git/blob - application/hub/main/class_HubConnector.php
Code syncronized with shipsimu code base
[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                 // Tidy up a little
44                 $this->removeSystemArray();
45                 $this->removeNumberFormaters();
46         }
47
48         /**
49          * Creates an instance based on the (IP) address and port number of this
50          * class. Next it tries to connect to the specified peer and communicates
51          * to it over a socket
52          *
53          * @param               $address                                The peer's IP address
54          * @param               $port                           The peer's port number
55          * @param               $hubInstance                    An instance of a HubCoreLoop class
56          * @return      $connector                      An instance of this class
57          * @throws      HubHelloException               If HELLO retries reached maximum
58          */
59         public final static function createHubConnectorByAddressPort ($address, $port, HubCoreLoop $hubInstance) {
60                 // Get a new instance of this class
61                 $connector = new HubConnector();
62
63                 // Connect to the given address and IP number
64                 $connector->aquireConnectionToAddress($address, $port);
65
66                 // Message to console
67                 $hubInstance->getOutputInstance()->output(sprintf("[%s] Sending %s request to hub %s:%d...",
68                         __METHOD__,
69                         $connector->getConfigInstance()->readConfig("hub_peer_hello"),
70                         $address,
71                         $port
72                 ));
73
74                 // Get a HubPeer instance
75                 $peerInstance = HubPeer::createHubPeerBySocket($connector->getSocketResource(), $hubInstance);
76
77                 // Send a HELLO to the master hub
78                 $helloed = 0; $retries = 0;
79                 while (!$peerInstance->ifHelloReplied()) {
80                         // Within timeout?
81                         if ((time() - $helloed) >= $connector->getConfigInstance()->readConfig("hub_hello_timeout")) {
82                                 // Send HELLOs out in periodic times
83                                 $peerInstance->sendMessage($connector->getConfigInstance()->readConfig("hub_peer_hello"));
84                                 $helloed = time(); $retries++;
85                                 if ($retries == $connector->getConfigInstance()->readConfig("hub_hello_retires")) {
86                                         // Maximum retries reached
87                                         throw new HubHelloException(
88                                                 array(
89                                                         'this'  => $connector,
90                                                         'peer'  => $peerInstance
91                                                 ), HubCoreLoop::EXCEPTION_HELLO_TIMED_OUT
92                                         );
93                                 }
94                         } // END - if
95                 } // END - while
96
97                 // Set the peer instance
98                 $connector->setPeerInstance($peerInstance);
99
100                 // Return the instance
101                 return $connector;
102         }
103
104         /**
105          * Aquires a socket link to a specified IP address and port number. It
106          * throws subclasses of SocketException-s if the peer is down or not
107          * responding. If the connection is up it writes it's resource into
108          * the attribute $socketResource and waits for incoming data packages.
109          *
110          * @param               $address                                The peer's IP address
111          * @param               $port                           The peer's port number
112          * @return      void
113          * @throws      SocketCreationException If creation of the socket wents wrong
114          * @throws      SocketConnectException  If the connection was not established
115          */
116         public function aquireConnectionToAddress ($address, $port) {
117                 // Create a socket for binding to the address
118                 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
119
120                 // Was it a success?
121                 if (!is_resource($socket)) {
122                         // This fails! :(
123                         throw new SocketCreationException(
124                                 array(
125                                         'this' => $this,
126                                         'code' => socket_last_error()
127                                 ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM
128                         );
129                 } // END - fi
130
131                 // Now connect to the peer
132                 if (@socket_connect($socket, $address, $port) === false) {
133                         // Something wents wrong!
134                         throw new SocketConnectException (
135                                 array(
136                                         'this'  => $this,
137                                         'code'  => socket_last_error()
138                                 ), HubCoreLoop::EXCEPTION_SOCKET_PROBLEM
139                         );
140                 } // END - if
141
142                 // Set non-blocking mode
143                 @socket_set_nonblock($socket);
144
145                 // Set the socket
146                 $this->socketResource = $socket;
147         }
148
149         /**
150          * Getter for current socket
151          *
152          * @return      $socketResource The current socket resource or null if not set
153          */
154         public final function getSocketResource() {
155                 return $this->socketResource;
156         }
157
158         /**
159          * Setter for a HubPeer instance
160          *
161          * @param               $peerInstance           An instance of a HubPeer class
162          * @return      void
163          */
164         public final function setPeerInstance (HubPeer $peerInstance) {
165                 $this->peerInstance = $peerInstance;
166         }
167
168         /**
169          * Handles any incoming master requests
170          *
171          * @return      void
172          */
173         public function handleMasterRequests () {
174                 // Just ask the peer instance
175                 $command = $this->peerInstance->handleMasterRequests();
176         }
177
178 } // END - class
179 ?>