X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=framework%2Fmain%2Fclasses%2Flistener%2Fsocket%2Fclass_SocketFileListener.php;fp=framework%2Fmain%2Fclasses%2Flistener%2Fsocket%2Fclass_SocketFileListener.php;h=1b12a3a61859991de2e2d8ce503a3a532a40c6ac;hb=78a010fef84895720e796842208f01dfb619c332;hp=0000000000000000000000000000000000000000;hpb=7629f2314d517561d4301ddfb068a797b6ed8700;p=core.git diff --git a/framework/main/classes/listener/socket/class_SocketFileListener.php b/framework/main/classes/listener/socket/class_SocketFileListener.php new file mode 100644 index 00000000..1b12a3a6 --- /dev/null +++ b/framework/main/classes/listener/socket/class_SocketFileListener.php @@ -0,0 +1,223 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class SocketFileListener extends BaseListener implements Listenable { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Set the protocol to file + $this->setProtocolName('file'); + } + + /** + * Creates an instance of this class + * + * @return $listenerInstance An instance a prepared listener class + */ + public final static function createSocketFileListener () { + // Get new instance + $listenerInstance = new SocketFileListener(); + + // Return the prepared instance + return $listenerInstance; + } + + /** + * Initializes the listener by setting up the required socket server + * + * @return void + */ + public function initListener() { + // Init socket + $mainSocket = socket_create(AF_UNIX, SOCK_STREAM, 0); + + // Is the socket resource valid? + if (!is_resource($mainSocket)) { + // Something bad happened + throw new InvalidSocketException(array($this, $mainSocket), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Get socket error code for verification + $socketError = socket_last_error($mainSocket); + + // Check if there was an error else + if ($socketError > 0) { + // Handle this socket error with a faked recipientData array + $this->handleSocketError(__METHOD__, __LINE__, $mainSocket, array('null', '0')); + } // END - if + + // Create file name + $socketFile = self::createTempPathForFile($this->getConfigInstance()->getConfigEntry('ipc_socket_file_name')); + + // Debug message + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: socketFile=' . $socketFile . ' ...'); + + // File name must not be empty + assert(!empty($socketFile)); + + // Is the file there? + if ((self::isReachableFilePath($socketFile)) && (file_exists($socketFile))) { + // Old socket found + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: WARNING: Old socket at ' . $socketFile . ' found. Will not start.'); + + // Shutdown this socket + $this->shutdownSocket($mainSocket); + + // Quit here + exit; + } // END - if + + // Debug message + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: Binding to ' . $socketFile . ' ...'); + + // Try to bind to it + if (!socket_bind($mainSocket, $socketFile)) { + // Handle error here + $this->handleSocketError(__METHOD__, __LINE__, $mainSocket, array($socketFile, '0')); + /* + // Get socket error code for verification + $socketError = socket_last_error($mainSocket); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $this->shutdownSocket($mainSocket); + + // And throw again + throw new InvalidSocketException(array($this, $mainSocket, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + */ + } // END - if + + // Start listen for connections + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: Listening for connections.'); + if (!socket_listen($mainSocket)) { + // Handle this socket error with a faked recipientData array + $this->handleSocketError(__METHOD__, __LINE__, $mainSocket, array($socketFile, '0')); + /* + // Get socket error code for verification + $socketError = socket_last_error($mainSocket); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $this->shutdownSocket($mainSocket); + + // And throw again + throw new InvalidSocketException(array($this, $mainSocket, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + */ + } // END - if + + // Now, we want non-blocking mode + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: Setting non-blocking mode.'); + if (!socket_set_nonblock($mainSocket)) { + // Handle this socket error with a faked recipientData array + $this->handleSocketError(__METHOD__, __LINE__, $mainSocket, array($socketFile, '0')); + /* + // Get socket error code for verification + $socketError = socket_last_error($mainSocket); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $this->shutdownSocket($mainSocket); + + // And throw again + throw new InvalidSocketException(array($this, $mainSocket, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + */ + } // END - if + + // Set the main socket + $this->registerServerSocketResource($mainSocket); + + // Initialize the peer pool instance + $poolInstance = ObjectFactory::createObjectByConfiguredName('application_pool_class', array($this)); + + // Add main socket + $poolInstance->addPeer($mainSocket, BaseConnectionHelper::CONNECTION_TYPE_SERVER); + + // And add it to this listener + $this->setPoolInstance($poolInstance); + + // Initialize iterator for listening on packages + $iteratorInstance = ObjectFactory::createObjectByConfiguredName('socket_listen_iterator_class', array($poolInstance->getPoolEntriesInstance())); + + // Rewind it and remember it in this class + $iteratorInstance->rewind(); + $this->setIteratorInstance($iteratorInstance); + + // Initialize the raw data handler + $handlerInstance = ObjectFactory::createObjectByConfiguredName('socket_raw_data_handler_class'); + + // Set it in this class + $this->setHandlerInstance($handlerInstance); + + // Output message + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: Socket listener now ready on socket ' . $socketFile . ' for service.'); + } + + /** + * "Listens" for incoming network packages + * + * @return void + */ + public function doListen() { + // Call super method + $this->doListenSocketSelect(''); + } + + /** + * Checks whether the listener would accept the given package data array + * + * @param $packageData Raw package data + * @return $accepts Whether this listener does accept + */ + public function ifListenerAcceptsPackageData (array $packageData) { + $this->partialStub('Need to implement this method.'); + } + + /** + * Monitors incoming raw data from the handler and transfers it to the + * given receiver instance. + * + * @return void + */ + public function monitorIncomingRawData () { + $this->partialStub('Need to implement this method.'); + } + +}