首页 > php > httpsqs配置记录&php client

httpsqs配置记录&php client

2011年7月13日 effect 发表评论 阅读评论

什么是httpsqs?

基于http的开源队列服务,使用Tokyo Cabinet 的 B+Tree Key/Value来做持久化存储。

适用于什么应用场景?

比较适合于比较慢而又没有特别高的时效性的应用。比如发送邮件(用户进行了某个操作,需要发送邮件给他的email账户通知。)、图片裁剪、视频转换、日志记录等。这些时效性要求不怎么高,这样就可以采用异步方式 ,让后台来集中处理,可以降低前台的服务压力。

具有什么特点?

支持http GET/POST协议,所以支持HTTP协议的都可以和他通信。

非常快速

高并发

更加详细的内容见官方网站:http://blog.s135.com/httpsqs/

官方提供了两种php client。1)php扩展(门槛高、不使用于win下的用户) 2)httpsqs_client.php (这个代码真不敢恭维)。所以自己写了一个httpsqs的类,供大家使用。

<!--?php class Httpsqs{ 	private $host; 	private $port; 	private $auth; 	private $charset; 	private static $sockets=array(); 	public function __construct($host,$port,$auth='',$charset='utf-8'){ 		$this--->host = $host;
		$this-&gt;port = $port;
		$this-&gt;auth = $auth;
		$this-&gt;charset = $charset;
	}
 
	public function get($name,$kt=0){
		$query  = $this-&gt;build_query($name,'get');
		return $this-&gt;execute($query,'GET','',$kt);
	}
 
	public function put($name,$body,$kt=0){
		$query = $this-&gt;build_query($name,'put');
		return $this-&gt;execute($query,'POST',$body,$kt);
	}
 
	public function reset($name){
		$query = $this-&gt;build_query($name,'reset');
		$r = $this-&gt;execute($query);
		if($r &amp;&amp; $r['data'] == "HTTPSQS_RESET_OK"){
			return true;
		}
		else return false;
	}
 
	public function status($name,$type='text'){
		if($type=='json'){
			$cmd = 'status_json';
		}
		else{
			$cmd = 'status';
		}
		$query = $this-&gt;build_query($name,$cmd);
		$r = $this-&gt;execute($query);
		if($r== false || $r['data']==false || $r['data']=='HTTPSQS_ERROR'){
			return false;
		}
		return $r['data'];
	}
 
	public function view($name,$pos){
		$query = $this-&gt;build_query($name,'view',array("pos=".$pos));
		$r = $this-&gt;execute($query);
		if($r==false || $r['data']==false || $r['data']=='HTTPSQS_ERROR'){
			return false;
		}
		else return $r['data'];
	}
 
	private function build_query($name,$cmd,$extra=array()){
		$tmp  = array("name=".$name,"opt=".$cmd);
		if($this-&gt;auth){
			$tmp[]="auth=".$this-&gt;auth;
		}
		$tmp[]="charset=".$this-&gt;charset;
		$tmp = array_merge($tmp , $extra);
		return '/?'.implode('&amp;',$tmp);
	}
 
	private function execute($query,$type='GET',$body='',$kt=0){
		if($kt==1){
			$key = md5($this-&gt;host.':'.$this-&gt;port);
			if(!isset(self::$sockets[$key])){
				self::$sockets[$key] = fsockopen($this-&gt;host,$this-&gt;port,$error,$errstr,5);
			}
			$socket = self::$sockets[$key];
		}
		else{
			$socket = fsockopen($this-&gt;host,$this-&gt;port,$error,$errstr,5);
		}
		if(!$socket){
			return false;
		}
		$out = "{$type} {$query} HTTP/1.1\r\n";
		$out .="Host: {$this-&gt;host}\r\n";
		if($type=='POST'){
			$out.="Content-Length: ".strlen($body)."\r\n";
		}
		if($kt==0){
			$out .="Connection: close\r\n";
		}
		else{
			$out .="Connection: Keep-Alive\r\n";
		}
		$out .="\r\n";
		if($type=='POST' &amp;&amp; $body){
			$out .=$body;
		}
		fwrite($socket,$out);
		$line = trim(fgets($socket));
		list($proto,$rcode,$result) = explode(" ",$line);
		$len = -1;
		$pos_value = 0;
		while(($line = trim(fgets($socket)))!=""){
			if(strstr($line,'Content-Length:')){
				list($cl,$len) = explode(" ",$line);
			}
			elseif(strstr($line,"Pos:")){
				list($pos_key,$pos_value) = explode(" ",$line);
			}
		}
		if($len&lt;0){ 			return false; 		} 		$body = @fread($socket,$len); 		if($kt==0){ 			fclose($socket); 		} 		return array( 			'pos'=&gt;intval($pos_value),
			'data'=&gt;$body
		);
	}
}

使用demo:

//get
$httpsqs = new Httpsqs('192.168.219.128','1218');
$r = $httpsqs-&gt;get('my_query');
 
//put
$httpsqs = new Httpsqs('192.168.219.128','1218');
$r = $httpsqs-&gt;put('my_query',"my_query_value");
 
//其他的请看源码

后感:
这个队列服务真的很实用,以前也有不少类似的应用,可以异步操作,实现方式是通过日志,比如每5分钟创建一个日志文件,然后每隔5分钟来处理,这样的风险很大,很可能造成数据的丢失等。有了这个,居多的应用都可以实现,异步发邮件,异步打日志,异步裁剪图片等等。

分类: php 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.