Location: PHPKode > projects > Simple Way to Usenet > swun/libs/swun/rpc/hellarpc_net.class.php
<?php
/**
 *  
 * @author  Benjamin Gillissen <hide@address.com>
 * 
 *	**************************************************************

	Copyright (C) 2009  Benjamin Gillissen
	
	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 2
	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 at:
	http://www.gnu.org/copyleft/gpl.html

 *	**************************************************************
 */

if (!function_exists('_xmlrpcs_listmethods') ){
	$p = CORE::getdeps(PATH_LIBS, 'xmlrpcs', NULL, 'inc', 'php');
	if ( FALSE === $p ){
		errors::raise('Missing XMLRpc librairies : not found in '.PATH_LIBS, CORE_LOG_ALERT, 'RPC');
	}
	include($p);
	$p = CORE::getdeps(PATH_LIBS, 'xmlrpc', NULL, 'inc', 'php');
	if ( FALSE === $p ){
		errors::raise('Missing XMLRpc librairies : not found in '.PATH_LIBS, CORE_LOG_ALERT, 'RPC');
	}
	include($p);
}

class hellarpc_net {
	
	private static $_RPC;		//xml-rpc conn handler
	private static $DFTO = 300;	//default connection Timeout
	private $lastreq;			//last request stamp
	private $RID = NULL;		//rpcID
	private $conf;				//rpc conf
	
	public function __construct($rid, $conf){
		$this->conf = $this->validconf($conf);
		if ( FALSE === $this->conf ){
			errors::raise('Invalid Configuration for rpc "'.$rid.'"', CORE_LOG_ERROR, 'RPC');
			return;
		}
		//errors::raise('HellaRPC loaded to connect to : '.$this->conf['host'].':'.$this->conf['port'], CORE_LOG_INFO, 'RPC');
		$this->RID = $rid;
		if ( !chrono::isinit('hellarpc_net') ){ chrono::init('hellarpc_net'); }
	}
	
	private function validconf($conf){
		if( !isset($conf['host']) ){
			//raise warning
			$conf['host'] = '127.0.0.1';
		} elseif (! isset($conf['port']) ){
			//raise notice
			$conf['port'] = '8760';
		} elseif (! isset($conf['user']) ){
			//raise warning
			$conf['user'] = 'hellanzb';
		} elseif (! isset($conf['conTO']) ){
			//raise warning
			$conf['conTO'] = self::$DFTO;
		} elseif (! isset($conf['pass']) ){
			return FALSE;
		}
		return $conf;
	}
	
	public function conn_need_revive(){
		if ( !isset(self::$_RPC[$this->RID]) ){ return TRUE; }
		$o = ( $this->lastreq <= bcsub(chrono::get_microtime(), $this->conf['conTO'], 4) );
		if ( $o ){ errors::raise('RPC '.$this->RID.' connection is timedout, reconnecting.', CORE_LOG_DEBUG, 'RPC'); }
		return  $o;
	}
	
	public function connect(){
		if ( $this->RID === NULL ){ return FALSE; }
		if ( !isset(self::$_RPC[$this->RID]) ){
			self::$_RPC[$this->RID] = new xmlrpc_client('', $this->conf['host'], $this->conf['port']);
			self::$_RPC[$this->RID]->setCredentials($this->conf['user'], $this->conf['pass']);
			self::$_RPC[$this->RID]->setDebug(0);
		}
		$q = new xmlrpcmsg("status", "");
		$r = self::$_RPC[$this->RID]->send($q);
		unset($q);		
		if ( !$r->faultCode() ){
			errors::raise('Connection success to '.$this->RID, CORE_LOG_NOTICE, 'RPC');
			$this->lastreq = chrono::get_microtime();
			return TRUE;
		}
		errors::raise('Connection failure to '.$this->RID.': '.htmlspecialchars( $r->faultString() ), CORE_LOG_ERROR, 'RPC');
		unset(self::$_RPC[$this->RID]);
		return FALSE;
	}
	
	public function getstatus(){
		$chr = chrono::start('hellarpc_net');
		if ( $this->conn_need_revive() ){ if ( !$this->connect() ){ chrono::pause('hellarpc_net', $chr);return FALSE; } }
		$q = new xmlrpcmsg("status", "");
		$r = self::$_RPC[$this->RID]->send($q);
		unset($q);
		if ( !$r->faultCode() ){
			$o = php_xmlrpc_decode( $r->value() );
		} else {
			errors::raise('RPC Request failure, Status : '.htmlspecialchars( $r->faultString() ), CORE_LOG_ERROR, 'RPC');
			$o = FALSE;
		}
		$this->lastreq = chrono::get_microtime();
		chrono::pause('hellarpc_net', $chr);
		return $o;
	}
	
	private function rpcall($msg, $arg=NULL){
		$chr = chrono::start('hellarpc_net');
		if ( $this->conn_need_revive() ){ if ( !$this->connect() ){ chrono::pause('hellarpc_net', $chr);return FALSE; } }
		if ( $arg === NULL ){
			$q = new xmlrpcmsg($msg, "");
		} else {
			$q = new xmlrpcmsg($msg, $arg);
		}
		$r = self::$_RPC[$this->RID]->send($q);
		unset($q);
		if ( !$r->faultCode() ){ chrono::pause('hellarpc_net', $chr);return TRUE; }
		errors::raise("RPC Call error, $msg : ".htmlspecialchars( $r->faultString() ), CORE_LOG_ERROR, 'RPC');
		chrono::pause('hellarpc_net', $chr);
		return FALSE;
	}
	
	public function cancel($id=NULL){
		if ( $id===NULL ){
			return $this->rpcall("cancel");
		} else {
			$buf[] = new xmlrpcval($id, "string");
			$r = $this->rpcall("dequeue", $buf);
			unset($buf);
			return $r;
		}
	}
	
	public function enqueue($did){ 
		$buf[] = new xmlrpcval($did, "string");
		$r = $this->rpcall("enqueuenewzbin", $buf); 
		unset($buf);
		return $r;
	}
	
	public function pause(){ return $this->rpcall("pause"); }
	
	public function resume(){ return $this->rpcall("continue"); }
	
	public function setrate($rate){ 
		$buf[] = new xmlrpcval($rate, "string");
		$r = $this->rpcall("maxrate", $buf); 
		unset($buf);
		return $r;
	}
	
	public function force($id){ 
		$buf[] = new xmlrpcval($id, "string");
		$r = $this->rpcall("force", $buf); 
		unset($buf);
		return $r;
	}
	
	public function moveup($id){ 
		$buf[] = new xmlrpcval($id, "string");
		$r = $this->rpcall("up", $buf); 
		unset($buf);
		return $r;
	}
	
	public function movedown($id){ 
		$buf[] = new xmlrpcval($id, "string");
		$r = $this->rpcall("down", $buf); 
		unset($buf);
		return $r;
	}
	
	public function movetop($id){ 
		$buf[] = new xmlrpcval($id, "string");
		$r = $this->rpcall("next", $buf); 
		unset($buf);
		return $r;
	}
	
	public function movebot($id){ 
		$buf[] = new xmlrpcval($id, "string");
		$r = $this->rpcall("last", $buf); 
		unset($buf);
		return $r;
	}
}
Return current item: Simple Way to Usenet