ircbot/Classes/Connection/ConnectionHandler.php
Jan Philipp Timme 2c5e520c9f [TASK] Added function for clients, so they're able to send initial data right after connecting to a server.
[TASK] Restructured parts of the core to support sending data right after connecting.
[TASK] Adapted core part for automatic reconnect to support sending initial data, too.
2011-06-25 22:13:53 +00:00

412 lines
9.0 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
*/
public 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
*/
public function __destruct() {
unset($this->socketHandler);
}
/**
* Injector for the internal ConnectionPool access.
* @param Connection_ConnectionPool $connectionPool
* @return void
*/
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
* @return void
*/
public function setIPv6($IPv6) {
$this->IPv6 = $IPv6;
}
/**
* Sets reconnect_on_disconnect flag.
* @param boolean $reconnect
* @return void
*/
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() {
$bufferContent = $this->buffer_outgoing->getAllBufferContents();
//this might not be cool, but it should do.
if($bufferContent === "") return TRUE;
$result = $this->socketHandler->write($bufferContent);
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();
}
}
?>