[TASK] Added a WrongDatatypeException [TASK] Started to implement the ProtocolHandler in a different way. [TASK] Started to put buffers into the ProtocolHandler. [!!!] Committing broken code.
		
			
				
	
	
		
			406 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			406 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * This class is a decorator for the class SocketHandler.
 | |
|  * It provides a buffer for the SocketHandler, so reading and writing
 | |
|  * a full line won't be that much pain.
 | |
|  * @author jpt
 | |
|  * @package Connection
 | |
|  * @depends Socket
 | |
|  * @depends Misc
 | |
|  */
 | |
| class Connection_ConnectionHandler {
 | |
| 
 | |
| 	/**
 | |
| 	 * Buffer that contains incoming data.
 | |
| 	 * Contents were received from the SocketHandler.
 | |
| 	 * This buffer does not use a linebreak, it's a temporary store for data.
 | |
| 	 * @var Misc_Buffer
 | |
| 	 */
 | |
| 	protected $buffer_incoming;
 | |
| 
 | |
| 	/**
 | |
| 	 * Buffer that contains outgoing data.
 | |
| 	 * Contents will be sent to the SocketHandler.
 | |
| 	 * This buffer does not use a linebreak, it's a temporary store for data.
 | |
| 	 * @var Misc_Buffer
 | |
| 	 */
 | |
| 	protected $buffer_outgoing;
 | |
| 
 | |
| 	/**
 | |
| 	 * Contains the instance of the SocketHandler class.
 | |
| 	 * According to the Liskov substitution principle, decoration pattern must be used in this case.
 | |
| 	 * @var Socket_SocketHandler
 | |
| 	 */
 | |
| 	protected $socketHandler;
 | |
| 
 | |
| 	/**
 | |
| 	 * @var Connection_ConnectionPool
 | |
| 	 */
 | |
| 	protected $connectionPool;
 | |
| 
 | |
| 	/**
 | |
| 	 * A boolean that indicates whether this Connection is a listening server socket or a usual client socket.
 | |
| 	 * @var boolean
 | |
| 	 */
 | |
| 	protected $is_server;
 | |
| 
 | |
| 	/**
 | |
| 	 * Unique Connection ID.
 | |
| 	 * @var int
 | |
| 	 */
 | |
| 	protected $id;
 | |
| 
 | |
| 	/**
 | |
| 	 * Connection Group.
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $group;
 | |
| 
 | |
| 	/**
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $protocol;
 | |
| 
 | |
| 	/**
 | |
| 	 * @var boolean
 | |
| 	 */
 | |
| 	protected $IPv6;
 | |
| 
 | |
| 	/**
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $host;
 | |
| 
 | |
| 	/**
 | |
| 	 * @var int
 | |
| 	 */
 | |
| 	protected $port;
 | |
| 
 | |
| 	/**
 | |
| 	 * @var boolean
 | |
| 	 */
 | |
| 	protected $reconnect_on_disconnect;
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls parent constructor.
 | |
| 	 * @param $socket
 | |
| 	 * @param $linebreak
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	function __construct($socket, $id, $group = "", $protocol = "") {
 | |
| 		$this->buffer_incoming = new Misc_Buffer();
 | |
| 		$this->buffer_outgoing = new Misc_Buffer();
 | |
| 		$this->socketHandler = new Socket_SocketHandler($socket);
 | |
| 		$this->id = $id;
 | |
| 		$this->group = $group;
 | |
| 		$this->protocol = $protocol;
 | |
| 		$this->is_server = FALSE;
 | |
| 		$this->host = "";
 | |
| 		$this->port = 0;
 | |
| 		$this->reconnect_on_disconnect = FALSE;
 | |
| 		$this->IPv6 = FALSE;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls parent destructor.
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	function __destruct() {
 | |
| 		unset($this->socketHandler);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Injector for the internal ConnectionPool access.
 | |
| 	 * @param Connection_ConnectionPool $connectionPool
 | |
| 	 */
 | |
| 	public function injectConnectionPool($connectionPool) {
 | |
| 		$this->connectionPool = $connectionPool;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function getProtocol() {
 | |
| 		return $this->protocol;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return string Connection Group
 | |
| 	 */
 | |
| 	public function getGroup() {
 | |
| 		return $this->group;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return int Connection ID
 | |
| 	 */
 | |
| 	public function getID() {
 | |
| 		return $this->id;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns whether this connection is a listening socket or a general client connection socket.
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function isServer() {
 | |
| 		return $this->is_server;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets the IPv6-flag.
 | |
| 	 * @param boolean $IPv6
 | |
| 	 */
 | |
| 	public function setIPv6($IPv6) {
 | |
| 		$this->IPv6 = $IPv6;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets reconnect_on_disconnect flag.
 | |
| 	 * @param boolean $reconnect
 | |
| 	 */
 | |
| 	public function setReconnect($reconnect) {
 | |
| 		$this->reconnect_on_disconnect = $reconnect;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets reconnect_on_disconnect flag.
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function getReconnect() {
 | |
| 		return $this->reconnect_on_disconnect;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * This function is called when socket_read() or socket_write() fail.
 | |
| 	 * It creates a new ConnectionHandler that will reconnect.
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	protected function shutdown() {
 | |
| 		$this->setConnected(FALSE);
 | |
| 		$this->close();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Reads from SocketHandler, writes into buffer_incoming.
 | |
| 	 * Returns a boolean that will indicate whether the socket is still okay.
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function readToBuffer() {
 | |
| 		$data = $this->socketHandler->read();
 | |
| 			//set connection status flag properly.
 | |
| 		if($data === "") {
 | |
| 			$this->shutdown();
 | |
| 			return FALSE;
 | |
| 		}
 | |
| 		$this->buffer_incoming->addData($data);
 | |
| 		return TRUE;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Writes the buffer_outgoing to the SocketHandler.
 | |
| 	 * Returns a boolean that will indicate whether the socket is still okay.
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function writeFromBuffer() {
 | |
| 		$result = $this->socketHandler->write($this->buffer_outgoing->getAllBufferContents());
 | |
| 		if($result === FALSE) {
 | |
| 			$this->shutdown();
 | |
| 			return FALSE;
 | |
| 		}
 | |
| 		return TRUE;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls error() on Socket_SocketHandler.
 | |
| 	 * @throws Socket_SocketExceptions
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function handleSocketError() {
 | |
| 		$this->socketHandler->error();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Determines whether this ConnectionHandler has data to read.
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function canRead() {
 | |
| 		return $this->buffer_incoming->hasData();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Determines whether this ConnectionHandler has data to write.
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function canWrite() {
 | |
| 		return $this->buffer_outgoing->hasData();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Reads new data into buffer_incoming.
 | |
| 	 * Returns a full line from buffer_incoming.
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function read() {
 | |
| 		return $this->buffer_incoming->getAllBufferContents();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Writes data into buffer_outgoing.
 | |
| 	 * Sends data from buffer_outgoing to the SocketHandler.
 | |
| 	 * @param $data
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function write($data) {
 | |
| 		$this->buffer_outgoing->addData($data);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return ressource
 | |
| 	 */
 | |
| 	public function accept() {
 | |
| 		return $this->socketHandler->accept();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function getRemoteName() {
 | |
| 		return $this->socketHandler->getRemoteName();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function getLocalName() {
 | |
| 		return $this->socketHandler->getLocalName();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function close() {
 | |
| 		return $this->socketHandler->close();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler, stores connection data.
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @param string $address
 | |
| 	 * @param int $port
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function connect($address, $port) {
 | |
| 		$this->host = $address;
 | |
| 		$this->port = $port;
 | |
| 		return $this->socketHandler->connect($address, $port);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler, uses stored connection data to fork a new instance of itself.
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @throws Exception_GeneralException
 | |
| 	 * @return Connection_ConnectionHandler
 | |
| 	 */
 | |
| 	public function reconnect() {
 | |
| 		if($this->reconnect_on_disconnect === FALSE) throw new Exception_GeneralException("Cannot reconnect: Reconnect-Flag not set!", 1290951385);
 | |
| 		if(empty($this->host) === TRUE) throw new Exception_GeneralException("Cannot reconnect: No host specified.", 1290950818);
 | |
| 		if(empty($this->port) === TRUE) throw new Exception_GeneralException("Cannot reconnect: No port specified.", 1290950844);
 | |
| 		$newConnectionHandler = $this->connectionPool->createTcpConnection($this->group, $this->protocol, $this->IPv6);
 | |
| 		$newConnectionHandler->setReconnect($this->getReconnect());
 | |
| 		$newConnectionHandler->connect($this->host, $this->port);
 | |
| 		return $newConnectionHandler;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function bind($address, $port) {
 | |
| 		$this->host = $address;
 | |
| 		$this->port = $port;
 | |
| 		return $this->socketHandler->bind($address, $port);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function listen() {
 | |
| 		$this->is_server = TRUE;
 | |
| 		return $this->socketHandler->listen();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function isConnected() {
 | |
| 		return $this->socketHandler->isConnected();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets the is_connected-flag in the socket handler.
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @param boolean $connected
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	private function setConnected($connected) {
 | |
| 		return $this->socketHandler->setConnected($connected);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @return boolean
 | |
| 	 */
 | |
| 	public function isListening() {
 | |
| 		return $this->socketHandler->isListening();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @throws Exception_SocketException
 | |
| 	 * @return ressource
 | |
| 	 */
 | |
| 	public function getSocket() {
 | |
| 		return $this->socketHandler->getSocket();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return Socket_SocketHandler
 | |
| 	 */
 | |
| 	public function getSocketHandler() {
 | |
| 		return $this->socketHandler;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Calls SocketHandler
 | |
| 	 * @see Socket_SocketHandler
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function hasBeenAccepted() {
 | |
| 		return $this->socketHandler->hasBeenAccepted();
 | |
| 	}
 | |
| 
 | |
| }
 | |
| ?>
 |