[TASK] Added the reconnect-flag that works now.

This commit is contained in:
Jan Philipp Timme 2010-11-28 16:38:03 +00:00
parent b318595783
commit a20a91bf12
7 changed files with 166 additions and 8 deletions

View File

@ -61,6 +61,16 @@ abstract class Client_AbstractClient {
*/ */
abstract public function loadConfig($config); abstract public function loadConfig($config);
/**
* Will reset the connectionStatus of the client.
* Implementation depends on the client.
* Should be used to reset internal variables.
* @return void
*/
public function resetConnectionStatus() {
}
/** /**
* @param int $id * @param int $id
*/ */

View File

@ -80,7 +80,24 @@ class Client_ClientManager {
foreach($connectionHandlers["read"] AS $connectionHandler) { foreach($connectionHandlers["read"] AS $connectionHandler) {
//handle disconnects //handle disconnects
if($connectionHandler->isConnected() === FALSE && $connectionHandler->isListening() === FALSE) { if($connectionHandler->isConnected() === FALSE && $connectionHandler->isListening() === FALSE) {
//check whether the reconnect-flag is set
if($connectionHandler->getReconnect() === TRUE) {
//have the connectionHandler do the reconnect.
$newConnectionHandler = $connectionHandler->reconnect();
//get the client and reset it.
$client = $this->clientPool[$connectionHandler->getID()];
$client->resetConnectionStatus();
//assign the client to the new connectionHandler.
$this->clientPool[$newConnectionHandler->getID()] = $client;
//get the config and assign it to the new connectionHandler, too.
$config = $this->configPool[$connectionHandler->getID()];
$this->configPool[$newConnectionHandler->getID()] = $config;
//remove old connection
$this->removeConnection($connectionHandler);
}
$this->removeClientForConnectionHandler($connectionHandler); $this->removeClientForConnectionHandler($connectionHandler);
//reconnect or not - this connectionHandler won't do that much.
continue;
} }
//handle accepted sockets, adopt them and treat them with care :-) //handle accepted sockets, adopt them and treat them with care :-)
if($connectionHandler->isListening() === TRUE) { if($connectionHandler->isListening() === TRUE) {

View File

@ -21,6 +21,14 @@ class Client_IrcClient extends Client_AbstractClient {
function __construct() { function __construct() {
$this->nick = "Serena"; $this->nick = "Serena";
$this->channels = array(); $this->channels = array();
$this->resetConnectionStatus();
}
/**
* Will reset the clients internal variables concerning the connection status.
* @return void
*/
public function resetConnectionStatus() {
$this->lines = 0; $this->lines = 0;
$this->got_001 = FALSE; $this->got_001 = FALSE;
$this->joined = FALSE; $this->joined = FALSE;
@ -34,8 +42,7 @@ class Client_IrcClient extends Client_AbstractClient {
*/ */
public function processContentObject($contentObject) { public function processContentObject($contentObject) {
$data = $contentObject->rawData; $data = $contentObject->rawData;
//echo "[RECV] ".$data; echo "[RECV] ".$data;
$this->clientManager->sendToGroup("srv", "[#".$this->ID."] ".$data."\r\n\r\n"); $this->clientManager->sendToGroup("srv", "[#".$this->ID."] ".$data."\r\n\r\n");
$return = ""; $return = "";

View File

@ -31,6 +31,11 @@ class Connection_ConnectionHandler {
*/ */
protected $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. * A boolean that indicates whether this Connection is a listening server socket or a usual client socket.
* @var boolean * @var boolean
@ -54,6 +59,26 @@ class Connection_ConnectionHandler {
*/ */
protected $protocol; protected $protocol;
/**
* @var boolean
*/
protected $IPv6;
/**
* @var string
*/
protected $host;
/**
* @var int
*/
protected $port;
/**
* @var boolean
*/
protected $reconnect_on_disconnect;
/** /**
* Calls parent constructor. * Calls parent constructor.
* @param $socket * @param $socket
@ -68,6 +93,10 @@ class Connection_ConnectionHandler {
$this->group = $group; $this->group = $group;
$this->protocol = $protocol; $this->protocol = $protocol;
$this->is_server = FALSE; $this->is_server = FALSE;
$this->host = "";
$this->port = 0;
$this->reconnect_on_disconnect = FALSE;
$this->IPv6 = FALSE;
} }
/** /**
@ -78,6 +107,14 @@ class Connection_ConnectionHandler {
unset($this->socketHandler); unset($this->socketHandler);
} }
/**
* Injector for the internal ConnectionPool access.
* @param Connection_ConnectionPool $connectionPool
*/
public function injectConnectionPool($connectionPool) {
$this->connectionPool = $connectionPool;
}
/** /**
* @return string * @return string
*/ */
@ -107,6 +144,40 @@ class Connection_ConnectionHandler {
return $this->is_server; 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. * Reads from SocketHandler, writes into buffer_incoming.
* Returns a boolean that will indicate whether the socket is still okay. * Returns a boolean that will indicate whether the socket is still okay.
@ -115,7 +186,11 @@ class Connection_ConnectionHandler {
*/ */
public function readToBuffer() { public function readToBuffer() {
$data = $this->socketHandler->read(); $data = $this->socketHandler->read();
if($data === "") return FALSE; //set connection status flag properly.
if($data === "") {
$this->shutdown();
return FALSE;
}
$this->buffer_incoming->addData($data); $this->buffer_incoming->addData($data);
return TRUE; return TRUE;
} }
@ -129,7 +204,10 @@ class Connection_ConnectionHandler {
public function writeFromBuffer() { public function writeFromBuffer() {
while($this->buffer_outgoing->hasLines()) { while($this->buffer_outgoing->hasLines()) {
$result = $this->socketHandler->write($this->buffer_outgoing->getNextLine()); $result = $this->socketHandler->write($this->buffer_outgoing->getNextLine());
if($result === FALSE) return FALSE; if($result === FALSE) {
$this->shutdown();
return FALSE;
}
} }
return TRUE; return TRUE;
} }
@ -219,15 +297,36 @@ class Connection_ConnectionHandler {
} }
/** /**
* Calls SocketHandler * Calls SocketHandler, stores connection data.
* @see Socket_SocketHandler * @see Socket_SocketHandler
* @throws Exception_SocketException * @throws Exception_SocketException
* @param string $address
* @param int $port
* @return void * @return void
*/ */
public function connect($address, $port) { public function connect($address, $port) {
$this->host = $address;
$this->port = $port;
return $this->socketHandler->connect($address, $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 * Calls SocketHandler
* @see Socket_SocketHandler * @see Socket_SocketHandler
@ -235,6 +334,8 @@ class Connection_ConnectionHandler {
* @return void * @return void
*/ */
public function bind($address, $port) { public function bind($address, $port) {
$this->host = $address;
$this->port = $port;
return $this->socketHandler->bind($address, $port); return $this->socketHandler->bind($address, $port);
} }
@ -257,6 +358,16 @@ class Connection_ConnectionHandler {
return $this->socketHandler->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 * @see Socket_SocketHandler
* @return boolean * @return boolean

View File

@ -50,6 +50,8 @@ class Connection_ConnectionPool {
public function createTcpConnection($group = "", $protocol = "RAW", $IPv6 = FALSE) { public function createTcpConnection($group = "", $protocol = "RAW", $IPv6 = FALSE) {
$socket = $this->socketPool->createTcpSocket($IPv6); $socket = $this->socketPool->createTcpSocket($IPv6);
$connectionHandler = new Connection_ConnectionHandler($socket, $this->nextID, $group, $protocol); $connectionHandler = new Connection_ConnectionHandler($socket, $this->nextID, $group, $protocol);
$connectionHandler->setIPv6($IPv6);
$connectionHandler->injectConnectionPool($this);
$this->addConnectionHandler($connectionHandler); $this->addConnectionHandler($connectionHandler);
return $connectionHandler; return $connectionHandler;
} }
@ -117,13 +119,13 @@ class Connection_ConnectionPool {
$connectionHandler = $this->getConnectionHandlerForSocketRessource($socket); $connectionHandler = $this->getConnectionHandlerForSocketRessource($socket);
switch($selectedType) { switch($selectedType) {
case "read": case "read":
if($connectionHandler->isServer() === FALSE) { if($connectionHandler->isServer() === TRUE) {
if($connectionHandler->readToBuffer() === FALSE) $this->removeConnectionHandler($connectionHandler);
} else {
$acceptedSocket = $connectionHandler->accept(); $acceptedSocket = $connectionHandler->accept();
$acceptedSocketHandler = new Connection_ConnectionHandler($acceptedSocket, $this->nextID, $connectionHandler->getGroup(), $connectionHandler->getProtocol()); $acceptedSocketHandler = new Connection_ConnectionHandler($acceptedSocket, $this->nextID, $connectionHandler->getGroup(), $connectionHandler->getProtocol());
$acceptedSocketHandler->hasBeenAccepted(); $acceptedSocketHandler->hasBeenAccepted();
$this->addConnectionHandler($acceptedSocketHandler); $this->addConnectionHandler($acceptedSocketHandler);
} else {
$connectionHandler->readToBuffer();
} }
break; break;
case "write": case "write":

View File

@ -65,6 +65,15 @@ class Socket_SocketHandler {
return $this->is_connected; return $this->is_connected;
} }
/**
* Sets is_connected-flag.
* @param boolean $connected
* @return void
*/
public function setConnected($connected) {
$this->is_connected = $connected;
}
/** /**
* @return boolean * @return boolean
*/ */
@ -206,6 +215,7 @@ class Socket_SocketHandler {
* @throws Exception_SocketException * @throws Exception_SocketException
*/ */
protected function error() { protected function error() {
if(is_resource($this->socket) === FALSE) throw new Exception_SocketException("No socket resource available!", 1290954177);
$errno = socket_last_error($this->socket); $errno = socket_last_error($this->socket);
$error = socket_strerror($errno); $error = socket_strerror($errno);
socket_clear_error(); socket_clear_error();

View File

@ -10,6 +10,7 @@ $clientManager->attachConfig(array(
"channels" => array("#mstasty") "channels" => array("#mstasty")
), $freenode); ), $freenode);
$freenode->connect("irc.freenode.net", 6667); $freenode->connect("irc.freenode.net", 6667);
$freenode->setReconnect(TRUE);
$freenode = $clientManager->createTcpConnection("freenode", "irc"); $freenode = $clientManager->createTcpConnection("freenode", "irc");
$clientManager->attachConfig(array( $clientManager->attachConfig(array(