From: Roland Häder Date: Tue, 30 May 2017 09:48:06 +0000 (+0200) Subject: Continued: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=4ca61d94242c5409fd8a7e2c8da859727e3e0503;p=hub.git Continued: - start rewriting writing raw data to socket towards StorableSocket - added more debug messages - renamed class constants to naming-convention - rewrote more code to StorableSocket (method writeBufferToSocketByArray() introduced) - added missing parameter $className - getConnectionClassNameFromSocket() is now fully rewritten Signed-off-by: Roland Häder --- diff --git a/application/hub/classes/container/socket/class_SocketContainer.php b/application/hub/classes/container/socket/class_SocketContainer.php index 7a2d594d3..f90e3e432 100644 --- a/application/hub/classes/container/socket/class_SocketContainer.php +++ b/application/hub/classes/container/socket/class_SocketContainer.php @@ -28,6 +28,7 @@ use CoreFramework\Visitor\Visitor; // Import SPL stuff use \BadMethodCallException; +use \InvalidArgumentException; use \LogicException; /** @@ -130,6 +131,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return $matches Whether $address matches with the one from package data */ public function ifAddressMatches ($unl) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: unl=%s - CALLED!', strtoupper($this->getSocketProtocol()), $unl)); + // Get current package data $packageData = $this->getPackageData(); @@ -139,6 +143,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // So, does both match? $matches = ((isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) && ($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] === $unl)); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: matches=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($matches))); + // Return result return $matches; } @@ -156,6 +163,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // So, does both match? $matches = ((is_resource($socketResource)) && ($socketResource === $this->getSocketResource())); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: matches=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($matches))); + // Return result return $matches; } @@ -178,6 +188,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Call the visitor $this->accept($visitorInstance); + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: EXIT!'); } /** @@ -198,6 +211,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Call the visitor $this->accept($visitorInstance); + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: EXIT!'); } /** @@ -276,6 +292,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If socket is invalid */ public function getSocketRecipient () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -291,6 +310,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita throw new LogicException(sprintf('packageData[%s] is not set.', NetworkPackage::PACKAGE_DATA_RECIPIENT)); } // END - if + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: packageData[%s]=%s - EXIT!', strtoupper($this->getSocketProtocol()), NetworkPackage::PACKAGE_DATA_RECIPIENT, $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])); + // Return it return $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]; } @@ -302,6 +324,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If socket is invalid */ public function getSocketRecipientAddress () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -317,6 +342,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Get address part $recipientAddress = $unlInstance->getUnlAddress(); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: recipientAddress=%s - EXIT!', strtoupper($this->getSocketProtocol()), $recipientAddress)); + // Return it return $recipientAddress; } @@ -328,6 +356,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If socket is invalid */ public function getSocketRecipientPort () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -343,6 +374,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Get port part $recipientPort = $unlInstance->getUnlPort(); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: recipientPort=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($recipientPort))); + // Return it return $recipientPort; @@ -354,6 +388,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return $isValidSocket Whether the stored socket is valid */ public function isValidSocket () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Get socket resource $socketResource = $this->getSocketResource(); @@ -361,6 +398,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // @TODO maybe add more checks? is_resource() is still to less $isValidSocket = (is_resource($socketResource)); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: isValidSocket=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($isValidSocket))); + // Return status return $isValidSocket; } @@ -372,6 +412,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If socket is invalid */ public function getLastSocketErrorCode () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -384,6 +427,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Get error code $errorCode = socket_last_error($socketResource); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: errorCode=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($errorCode))); + // Return it return $errorCode; } @@ -395,6 +441,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If socket is invalid */ public function getLastSocketErrorMessage () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -417,12 +466,18 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return $codeName Code name to used e.g. with some_$codeName_socket_error_class or so */ public function translateLastSocketErrorCodeToName () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Get last error code $errorCode = $this->getLastSocketErrorCode(); // Call "translate" method $codeName = $this->translateSocketErrorCodeToName($errorCode); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: codeName=%s - EXIT!', strtoupper($this->getSocketProtocol()), $codeName)); + // Return it return $codeName; } @@ -436,6 +491,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If socket is invalid */ public function bindSocketTo ($bindAddress, $bindPort = 0) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -445,6 +503,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Try to bind it to $result = socket_bind($this->getSocketResource(), $bindAddress, $bindPort); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: result=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($result))); + // Return result return $result; } @@ -456,6 +517,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If stored socket is invalid */ public function listenToSocket () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -465,6 +529,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Try to listen on socket $result = socket_listen($this->getSocketResource()); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: result=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($result))); + // Return result return $result; } @@ -476,6 +543,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If stored socket is invalid */ public function enableSocketNonBlocking () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -485,6 +555,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Try to set non-blocking I/O $result = socket_set_nonblock($this->getSocketResource()); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: result=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($result))); + // Return result return $result; } @@ -496,6 +569,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If stored socket is invalid */ public function enableSocketReuseAddress () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -505,6 +581,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Tries to set option $result = $this->setSocketOption(SOL_SOCKET, SO_REUSEADDR, 1); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: result=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($result))); + // Return result return $result; } @@ -551,6 +630,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @todo rewrite this! */ public function doShutdown () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -585,6 +667,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Mark this connection as shutted down $this->markConnectionShuttedDown(); + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: EXIT!'); } /** @@ -594,9 +679,15 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return $isValid Whether the provided connection type is valid */ public function isValidConnectionType ($connectionType) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: connectionType=%d - CALLED!', strtoupper($this->getSocketProtocol()), $connectionType)); + // Is it valid? $isValid = in_array($connectionType, $this->connectionTypes, TRUE); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: isValid=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($isValid))); + // Return result return $isValid; } @@ -608,6 +699,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If stored socket is invalid */ public function acceptNewIncomingSocket () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Should be valid socket if (!$this->isValidSocket()) { // Throw exception @@ -692,6 +786,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita $this->setPackageData($packageData); } // END - if + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: result=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($result))); + // Return result return $result; } @@ -702,6 +799,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return $result Whether the option has been set */ public function setSocketTimeoutOptions () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + // Array for timeout settings $options = array( // Seconds @@ -713,6 +813,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Call inner method $result = $this->setSocketOption(SOL_SOCKET, SO_RCVTIMEO, $options); + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: result=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($result))); + // Return result return $result; } @@ -723,6 +826,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return $result Whether OOB has been enabled */ public function enableSocketOutOfBandData () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: CALLED!', strtoupper($this->getSocketProtocol()))); + $this->partialStub('Please implement this method.'); } @@ -762,7 +868,7 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita */ public function registerInfoInstance (ShareableInfo $infoInstance) { // Trace message - /* NOSY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Calling infoInstance->getListenerInstance() ...', strtoupper($this->getSocketProtocol()))); + /* NOSY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Calling infoInstance->getListenerInstance() - CALLED!', strtoupper($this->getSocketProtocol()))); // Get listener/helper from info class $listenerInstance = $infoInstance->getListenerInstance(); @@ -785,6 +891,107 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Set it here for later usage $this->setHelperInstance($helperInstance); } + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: EXIT!'); + } + + /** + * Writes given buffer array to socket by calling socket_write(). The sent + * bytes are being returned in 2nd parameter, result of calling underlaying + * function is returned. + * + * If the data in given buffer array is to long, it will be truncated and + * sent-bytes counter being updated as well. + * + * @param $socketBuffer Buffer array, must contain some array elements + * @param $sentBytes Sent bytes + * @return $result Result of calling socket_write() + * @throws InvalidSocketException If stored socket is invalid + * @throws InvalidArgumentException If an array element is missing + */ + public function writeBufferToSocketByArray (array &$socketBuffer, &$sentBytes) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketBuffer()=%d,sentBytes=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketBuffer), $sentBytes)); + + // Should be valid socket + if (!$this->isValidSocket()) { + // Throw exception + throw new InvalidSocketException(array($this, $this->getSocketResource()), self::EXCEPTION_INVALID_SOCKET); + } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_DIFF])) { + // Opps, should not happen + throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_DIFF)); + } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA])) { + // Opps, should not happen + throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_ENCODED_DATA)); + } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE])) { + // Opps, should not happen + throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_BUFFER_SIZE)); + } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_SENT_BYTES])) { + // Opps, should not happen + throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_SENT_BYTES)); + } + + // Debug message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Sending out %d bytes,rawBufferSize=%d,diff=%d', strtoupper($this->getSocketProtocol()), strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]), $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE], $socketBuffer[NetworkPackage::RAW_INDEX_DIFF])); + + // Is some data still pending or sent all out? + if ($socketBuffer[NetworkPackage::RAW_INDEX_DIFF] >= 0) { + // Debug message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: MD5=%s', strtoupper($this->getSocketProtocol()), md5(substr($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], 0, ($socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE] - $socketBuffer[NetworkPackage::RAW_INDEX_DIFF]))))); + + // Send all out (encodedData is smaller than or equal buffer size) + $sentBytes = socket_write($this->getSocketResource(), $socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], ($socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE] - $socketBuffer[NetworkPackage::RAW_INDEX_DIFF])); + } else { + // Debug message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: MD5=%s', strtoupper($this->getSocketProtocol()), md5(substr($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], 0, $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE])))); + + // Send buffer size out + $sentBytes = socket_write($this->getSocketResource(), $socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE]); + } + + // Check if the operation was okay + // @TODO Maybe check more? + $result = ($sentBytes !== FALSE); + + // Debug message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: sentBytes[%s]=%d,result=%d', strtoupper($this->getSocketProtocol()), gettype($sentBytes), $sentBytes, intval($result))); + + // If there was an error, don't continue here + if ($result === FALSE) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socket_write() failed, please evalutate. - EXIT!', strtoupper($this->getSocketProtocol()))); + + // Failed delivery! + return FALSE; + } elseif (($sentBytes === 0) && (strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]) > 0)) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: All sent, returning TRUE ... - EXIT!', strtoupper($this->getSocketProtocol()))); + + // Nothing sent means all data has been sent + return TRUE; + } else { + // The difference between sent bytes and length of raw data should not go below zero + assert((strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]) - $sentBytes) >= 0); + + // Add total sent bytes + $socketBuffer[NetworkPackage::RAW_INDEX_SENT_BYTES] += $sentBytes; + + // Debug message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Sent out %d of %d bytes ...', strtoupper($this->getSocketProtocol()), $sentBytes, strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]))); + + // Cut out the last unsent bytes + $socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA] = substr($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], $sentBytes); + + // Calculate difference again + $socketBuffer[NetworkPackage::RAW_INDEX_DIFF] = $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE] - strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]); + } + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: result=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($result))); + + // Return result + return $result; } /** @@ -800,7 +1007,7 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws InvalidSocketException If the stored socket resource is no socket resource * @throws NoSocketErrorDetectedException If socket_last_error() gives zero back */ - public final function handleSocketError ($method, $line, array $socketData) { + public function handleSocketError ($method, $line, array $socketData) { // Trace message /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('HUB-SYSTEM: Handling socket errorCode=%d - CALLED!', $this->getLastSocketErrorCode())); @@ -832,6 +1039,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita // Finally clear the error because it has been handled $this->clearLastSocketError(); + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: EXIT!'); } /** @@ -843,6 +1053,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws UnsupportedSocketErrorHandlerException If the error handler is not implemented */ protected function getSocketErrorHandlerFromCode ($errorCode) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: errorCode=%d - CALLED!', strtoupper($this->getSocketProtocol()), $errorCode)); + // Create a name from translated error code $handlerName = 'handleSocketError' . self::convertToClassName($this->translateSocketErrorCodeToName($errorCode)); @@ -852,6 +1065,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita throw new UnsupportedSocketErrorHandlerException(array($this, $handlerName, $errorCode), BaseConnectionHelper::EXCEPTION_UNSUPPORTED_ERROR_HANDLER); } // END - if + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: handlerName=%d - EXIT!', strtoupper($this->getSocketProtocol()), $handlerName)); + // Return it return $handlerName; } @@ -869,6 +1085,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketBindingException The socket could not be bind to */ protected function handleSocketErrorPermissionDenied (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -891,6 +1110,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketConnectionException The connection attempts fails with a time-out */ protected function handleSocketErrorConnectionTimedOut (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -913,6 +1135,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketConnectionException The connection attempts fails with a time-out */ protected function handleSocketErrorResourceUnavailable (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -935,6 +1160,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketConnectionException The connection attempts fails with a time-out */ protected function handleSocketErrorConnectionRefused (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -957,6 +1185,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketConnectionException The connection attempts fails with a time-out */ protected function handleSocketErrorNoRouteToHost (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -979,6 +1210,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketConnectionException The connection attempts fails with a time-out */ protected function handleSocketErrorOperationAlreadyProgress (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -1001,6 +1235,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketConnectionException The connection attempts fails with a time-out */ protected function handleSocketErrorConnectionResetByPeer (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -1023,6 +1260,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @throws SocketOperationException The connection attempts fails with a time-out */ protected function handleSocketErrorOperationNotSupported (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + // Get socket error code for verification $socketError = $this->getLastSocketErrorCode(); @@ -1044,6 +1284,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return void */ protected function handleSocketErrorOperationInProgress (array $socketData) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: socketData()=%d - CALLED!', strtoupper($this->getSocketProtocol()), count($socketData))); + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-HELPER: Operation is now in progress, this is usual for non-blocking connections and is no bug.'); } @@ -1059,6 +1302,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita * @return $errorName The translated name (all lower-case, with underlines) */ private function translateSocketErrorCodeToName ($errorCode) { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: errorCode=%d - CALLED!', strtoupper($this->getSocketProtocol()), $errorCode)); + // Nothing bad happened by default $errorName = StorableSocket::SOCKET_CONNECTED; @@ -1122,6 +1368,9 @@ class SocketContainer extends BaseHubContainer implements StorableSocket, Visita break; } // END - switch + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: errorName=%d - EXIT!', strtoupper($this->getSocketProtocol()), $errorName)); + // Return translated name return $errorName; } diff --git a/application/hub/classes/helper/connection/class_BaseConnectionHelper.php b/application/hub/classes/helper/connection/class_BaseConnectionHelper.php index 5fe5b8341..1fd16faff 100644 --- a/application/hub/classes/helper/connection/class_BaseConnectionHelper.php +++ b/application/hub/classes/helper/connection/class_BaseConnectionHelper.php @@ -12,6 +12,7 @@ use Hub\Network\Package\NetworkPackage; // Import framework stuff use CoreFramework\Factory\ObjectFactory; +use CoreFramework\Generic\FrameworkInterface; use CoreFramework\Registry\Registry; use CoreFramework\Registry\Registerable; use CoreFramework\Visitor\Visitable; @@ -139,12 +140,16 @@ class BaseConnectionHelper extends BaseHubSystemHelper implements Visitable, Reg * Static "getter" for this connection class' name * * @param $socketInstance An instance of a StorableSocket class + * @param $className Name of calling class * @return $class Expanded class name */ - public static function getConnectionClassNameFromSocket (StorableSocket $socketInstance) { - die(__METHOD__.':socketInstance='.print_r($socketInstance, TRUE)); + public static function getConnectionClassNameFromSocket (StorableSocket $socketInstance, $className) { + // Get recipient address/port + $recipientAddress = $socketInstance->getSocketRecipientAddress(); + $recipientPort = $socketInstance->getSocketRecipientPort(); + // Construct it - $class = $address . ':' . $port . ':' . $className; + $class = sprintf('%s:%d:%s', $recipientAddress, $recipientPort, $className); // ... and return it return $class; @@ -272,16 +277,16 @@ class BaseConnectionHelper extends BaseHubSystemHelper implements Visitable, Reg // Init array $encodedDataArray = array( - NetworkPackage::RAW_FINAL_HASH_INDEX => $this->currentFinalHash, - NetworkPackage::RAW_ENCODED_DATA_INDEX => $encodedData, - NetworkPackage::RAW_SENT_BYTES_INDEX => 0, - NetworkPackage::RAW_SOCKET_INDEX => $this->getSocketInstance(), - NetworkPackage::RAW_BUFFER_SIZE_INDEX => $bufferSize, - NetworkPackage::RAW_DIFF_INDEX => 0 + NetworkPackage::RAW_INDEX_FINAL_HASH => $this->currentFinalHash, + NetworkPackage::RAW_INDEX_ENCODED_DATA => $encodedData, + NetworkPackage::RAW_INDEX_SENT_BYTES => 0, + NetworkPackage::RAW_INDEX_SOCKET_INSTANCE => $this->getSocketInstance(), + NetworkPackage::RAW_INDEX_BUFFER_SIZE => $bufferSize, + NetworkPackage::RAW_INDEX_DIFF => 0 ); // Calculate difference - $diff = $encodedDataArray[NetworkPackage::RAW_BUFFER_SIZE_INDEX] - strlen($encodedDataArray[NetworkPackage::RAW_ENCODED_DATA_INDEX]); + $diff = $encodedDataArray[NetworkPackage::RAW_INDEX_BUFFER_SIZE] - strlen($encodedDataArray[NetworkPackage::RAW_INDEX_ENCODED_DATA]); // Push raw data to the package's outgoing stack $this->getPackageInstance()->getStackInstance()->pushNamed(NetworkPackage::STACKER_NAME_OUTGOING_STREAM, $encodedDataArray); @@ -296,7 +301,5 @@ class BaseConnectionHelper extends BaseHubSystemHelper implements Visitable, Reg //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: ' . $this->__toString() . ',shuttedDown=' . intval($this->shuttedDown)); return $this->shuttedDown; } -} -// [EOF] -?> +} diff --git a/application/hub/classes/package/class_NetworkPackage.php b/application/hub/classes/package/class_NetworkPackage.php index 115cfad7a..bb38964ea 100644 --- a/application/hub/classes/package/class_NetworkPackage.php +++ b/application/hub/classes/package/class_NetworkPackage.php @@ -48,7 +48,7 @@ use \Iterator; * implement the Compressor interface). If you don't want any compression (not * adviceable due to increased network load), please use the NullCompressor * class and encode it with BASE64 for a more error-free transfer over the - * Internet. + * network. * * For performance reasons, this class should only be instanciated once and then * used as a "pipe-through" class. @@ -265,32 +265,32 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R /** * Array index for final hash */ - const RAW_FINAL_HASH_INDEX = 'hash'; + const RAW_INDEX_FINAL_HASH = 'hash'; /** * Array index for encoded data */ - const RAW_ENCODED_DATA_INDEX = 'data'; + const RAW_INDEX_ENCODED_DATA = 'data'; /** * Array index for sent bytes */ - const RAW_SENT_BYTES_INDEX = 'sent'; + const RAW_INDEX_SENT_BYTES = 'sent'; /** * Array index for socket resource */ - const RAW_SOCKET_INDEX = 'socket'; + const RAW_INDEX_SOCKET_INSTANCE = 'socket'; /** * Array index for buffer size */ - const RAW_BUFFER_SIZE_INDEX = 'buffer'; + const RAW_INDEX_BUFFER_SIZE = 'buffer'; /** * Array index for diff between buffer and sent bytes */ - const RAW_DIFF_INDEX = 'diff'; + const RAW_INDEX_DIFF = 'diff'; /************************************************************************** * Protocol names * @@ -1018,49 +1018,25 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R // Init in this round sent bytes $sentBytes = 0; - // Assert on socket - assert(is_resource($encodedDataArray[self::RAW_SOCKET_INDEX])); + // Assert on socket instance + assert($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE] instanceof StorableSocket); + assert($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE]->isValidSocket()); // And deliver it - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: Sending out ' . strlen($encodedDataArray[self::RAW_ENCODED_DATA_INDEX]) . ' bytes,rawBufferSize=' . $encodedDataArray[self::RAW_BUFFER_SIZE_INDEX] . ',diff=' . $encodedDataArray[self::RAW_DIFF_INDEX]); - if ($encodedDataArray[self::RAW_DIFF_INDEX] >= 0) { - // Send all out (encodedData is smaller than or equal buffer size) - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: MD5=' . md5(substr($encodedDataArray[self::RAW_ENCODED_DATA_INDEX], 0, ($encodedDataArray[self::RAW_BUFFER_SIZE_INDEX] - $encodedDataArray[self::RAW_DIFF_INDEX])))); - $sentBytes = @socket_write($encodedDataArray[self::RAW_SOCKET_INDEX], $encodedDataArray[self::RAW_ENCODED_DATA_INDEX], ($encodedDataArray[self::RAW_BUFFER_SIZE_INDEX] - $encodedDataArray[self::RAW_DIFF_INDEX])); - } else { - // Send buffer size out - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: MD5=' . md5(substr($encodedDataArray[self::RAW_ENCODED_DATA_INDEX], 0, $encodedDataArray[self::RAW_BUFFER_SIZE_INDEX]))); - $sentBytes = @socket_write($encodedDataArray[self::RAW_SOCKET_INDEX], $encodedDataArray[self::RAW_ENCODED_DATA_INDEX], $encodedDataArray[self::RAW_BUFFER_SIZE_INDEX]); - } + if (!$encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE]->writeBufferToSocketByArray($encodedDataArray, $sentBytes)) { + // Something bad happened while writing to socket + $encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE]->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0')); + } // END - if - // If there was an error, we don't continue here - if ($sentBytes === FALSE) { - // Handle the error with a faked recipientData array - $this->handleSocketError(__METHOD__, __LINE__, $encodedDataArray[self::RAW_SOCKET_INDEX], array('0.0.0.0', '0')); - } elseif (($sentBytes === 0) && (strlen($encodedDataArray[self::RAW_ENCODED_DATA_INDEX]) > 0)) { - // Nothing sent means we are done + // If there was an error, don't continue here + if (($sentBytes === 0) && (strlen($encodedDataArray[self::RAW_INDEX_ENCODED_DATA]) > 0)) { + // Nothing sent means all data has been sent + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')'); + return; + } elseif (strlen($encodedDataArray[self::RAW_INDEX_ENCODED_DATA]) <= 0) { + // Abort here, all sent! //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')'); return; - } else { - // The difference between sent bytes and length of raw data should not go below zero - assert((strlen($encodedDataArray[self::RAW_ENCODED_DATA_INDEX]) - $sentBytes) >= 0); - - // Add total sent bytes - $encodedDataArray[self::RAW_SENT_BYTES_INDEX] += $sentBytes; - - // Cut out the last unsent bytes - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: Sent out ' . $sentBytes . ' of ' . strlen($encodedDataArray[self::RAW_ENCODED_DATA_INDEX]) . ' bytes ...'); - $encodedDataArray[self::RAW_ENCODED_DATA_INDEX] = substr($encodedDataArray[self::RAW_ENCODED_DATA_INDEX], $sentBytes); - - // Calculate difference again - $encodedDataArray[self::RAW_DIFF_INDEX] = $encodedDataArray[self::RAW_BUFFER_SIZE_INDEX] - strlen($encodedDataArray[self::RAW_ENCODED_DATA_INDEX]); - - // Can we abort? - if (strlen($encodedDataArray[self::RAW_ENCODED_DATA_INDEX]) <= 0) { - // Abort here, all sent! - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')'); - return; - } // END - if } // Push array back in stack diff --git a/application/hub/interfaces/container/socket/class_StorableSocket.php b/application/hub/interfaces/container/socket/class_StorableSocket.php index 68348ef4b..4d9931415 100644 --- a/application/hub/interfaces/container/socket/class_StorableSocket.php +++ b/application/hub/interfaces/container/socket/class_StorableSocket.php @@ -156,6 +156,21 @@ interface StorableSocket extends FrameworkInterface { */ function connectToSocketRecipient (); + /** + * Writes given buffer array to socket by calling socket_write(). The sent + * bytes are being returned in 2nd parameter, result of calling underlaying + * function is returned. + * + * If the data in given buffer array is to long, it will be truncated and + * sent-bytes counter being updated as well. + * + * @param $socketBuffer Buffer array, must contain some array elements + * @param $sentBytes Sent bytes + * @return $result Result of calling socket_write() + * @throws InvalidSocketException If stored socket is invalid + */ + function writeBufferToSocketByArray (array &$socketBuffer, &$sentBytes); + /** * Getter for socket procotol field * diff --git a/application/hub/interfaces/helper/connections/class_ConnectionHelper.php b/application/hub/interfaces/helper/connections/class_ConnectionHelper.php index 511bd8f6a..9093bac9f 100644 --- a/application/hub/interfaces/helper/connections/class_ConnectionHelper.php +++ b/application/hub/interfaces/helper/connections/class_ConnectionHelper.php @@ -52,9 +52,10 @@ interface ConnectionHelper extends HubHelper { * Static "getter" for this connection class' name * * @param $socketInstance An instance of a StorableSocket class + * @param $className Name of calling class * @return $class Expanded class name */ - static function getConnectionClassNameFromSocket (StorableSocket $socketInstance); + static function getConnectionClassNameFromSocket (StorableSocket $socketInstance, $className); /** * Getter for shuttedDown