3 * A general ConnectionHelper class
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class BaseConnectionHelper extends BaseHubHelper implements Registerable, ProtocolHandler {
28 private $protocol = 'invalid';
43 private $sentData = 0;
51 * Connect retries for this connection
53 private $retryCount = 0;
56 * Wether this connection is shutted down
58 private $shuttedDown = false;
61 * Protected constructor
63 * @param $className Name of the class
66 protected function __construct ($className) {
67 // Call parent constructor
68 parent::__construct($className);
70 // Register this connection helper
71 Registry::getRegistry()->addInstance('connection', $this);
75 * Getter for port number to satify ProtocolHandler
77 * @return $port The port number
79 public final function getPort () {
84 * Setter for port number to satify ProtocolHandler
86 * @param $port The port number
89 protected final function setPort ($port) {
96 * @return $protocol Used protocol
98 public final function getProtocol () {
99 return $this->protocol;
103 * Setter for protocol
105 * @param $protocol Used protocol
108 protected final function setProtocol ($protocol) {
109 $this->protocol = $protocol;
113 * Getter for IP address
115 * @return $address The IP address
117 public final function getAddress () {
118 return $this->address;
122 * Setter for IP address
124 * @param $address The IP address
127 protected final function setAddress ($address) {
128 $this->address = $address;
132 * "Accept" a visitor by simply calling it back
134 * @param $visitorInstance A Visitor instance
137 protected final function accept (Visitor $visitorInstance) {
138 // Just call the visitor
139 $visitorInstance->visitConnectionHelper($this);
143 * "Getter" for raw package data from a package array. This method does
144 * honor any unsend bytes in the back-buffer and the sending buffer size.
146 * @param $packageData Raw package data array
147 * @return $rawData Raw package data bytes
149 private function getRawDataFromPackageArray (array $packageData) {
150 // Get the fragmenter instance
151 $fragmenterInstance = ObjectFactory::createObjectByConfiguredName('package_fragmenter_class');
152 $fragmenterInstance->debugInstance();
159 * Sends raw package data to the recipient
161 * @param $packageData Raw package data
162 * @return $sentBytes Actual sent bytes to the peer
163 * @throws InvalidSocketException If we got a problem with this socket
165 public function sendRawPackageData (array $packageData) {
166 // We need to "package" all data. This is done by a implode()
167 $rawData = $this->getRawDataFromPackageArray($packageData);
169 // Get socket resource
170 $socketResource = $this->getSocketResource();
173 $sentBytes = @socket_write($socketResource, $rawData, $this->getConfigInstance()->getConfigEntry($this->getProtocol() . '_buffer_length') - $this->offset);
175 // If there was an error, we don't continue here
176 if ($sentBytes === false) {
177 // Get socket error code for verification
178 $socketError = socket_last_error($socketResource);
181 $errorMessage = socket_strerror($socketError);
183 // Shutdown this socket
184 $this->shutdownSocket($socketResource);
187 throw new InvalidSocketException(array($this, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
190 // The difference between sent bytes and length of raw data should not be below zero
191 assert((strlen($rawData) - $sentBytes) >= 0);
198 * Getter for real class name
200 * @return $class Name of this class
202 public function __toString () {
203 // Class name representation
204 $class = $this->getAddress() . ':' . $this->getPort() . ':' . parent::__toString();
211 * Checks wether the connect retry is exhausted
213 * @return $isExhaused Wether connect retry is exchausted
215 public final function isConnectRetryExhausted () {
216 // Construct config entry
217 $configEntry = $this->getProtocol() . '_connect_retry_max';
220 $isExhausted = ($this->retryCount >= $this->getConfigInstance()->getConfigEntry($configEntry));
227 * Increases the connect retry count
231 public final function increaseConnectRetry () {
236 * Marks this connection as shutted down
240 protected final function markConnectionShutdown () {
241 $this->shuttedDown = true;
245 * Getter for shuttedDown
247 * @return $shuttedDown Wether this connection is shutted down
249 public final function isShuttedDown () {
250 return $this->shuttedDown;