Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

队列服务开发

$
0
0

看了HTTPSQS,自己尝试开发了队列服务器。原理是借鉴HTTPSQS,只是通信协议层没有使用HTTP协议,而是自己的定的协议规则。

一是为了练手,练习检测内存泄露同时巩固指针的使用。

二是为了理解通信协议。

目前只支持Windows下的编译,后面会支持Linux。

我每次都是先在windows下开发,之后再到调试支持linux下的编译。因为Linux的桌面版真心蛋疼,还不如直接windows下开发,然后通过虚拟机下的调试来支持Linux快。


现有支持的功能:

1.创建队列

2.获取队列

3.插入队列

4.删除队列

5.清空队列

6.队列状态

后续还会支持事务,事务与队列的关系可以参考Redis的设计实现:http://www.redisbook.com/en/latest/feature/transaction.html


一、开发用到的库

1、libevent:通信框架

2、glib:跨平台的基础库

3、Tokyo Cabinet:高效的数据存储


二、服务器端通信协议及队列原理

通信协议图:



单个队列图:



多个队列间的关系图直接借用HTTPSQS的:



三、PHP客户端的请求

<?php
define('QUEUE_MAX_LENGTH', 10000);

class QueueSocket{
	private $socket;
	private $errmsg;

	public function __construct($host, $port){
		$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
		socket_bind($this->socket, $host);
		if(!socket_connect($this->socket, $host, $port)){
			$this->set_errmsg("Unable to connect<pre>".socket_strerror(socket_last_error())."</pre>");
			return false;
		}

		return true;
	}

	public function send($cmd, $content){
		if(!is_array($content) || !$content) {
			return false;
		}

		$params = false;
		foreach($content as $key=>$value){
			$params[] = strtoupper($key)."={$value}";
		}

		$params = join('&', $params)."\r\n";
		$binary = pack("a20i1a*", strtoupper($cmd), strlen($params), $params);

		socket_write($this->socket, $binary, strlen($binary));
	}

	public function read(){
		$response = socket_read($this->socket, 256, PHP_BINARY_READ);

		if($response) {
			$response = json_decode($response, true);
		}else{
			return false;
		}

		if(isset($response['errno']) && $response['errno'] > 0) 
			$this->set_errmsg($response['errmsg']);

		return $response;
	}

	public function set_errmsg($msg){
		$this->errmsg = $msg;
	}

	public function get_errmsg(){
		return $this->errmsg;
	}

	public function __destory(){
		socket_close($this->socket);
	}
}

class QueueClient extends QueueSocket{
	private $appkey;

	public function __construct($host, $port, $appkey){
		$this->appkey = $appkey;
		parent::__construct($host, $port);
	}

	public function create_new_queue($queue_name, $max_length = QUEUE_MAX_LENGTH){
		$this->send("CREATE", array('queue_name'=>$queue_name, 'max_length'=>$max_length, 'appkey'=>$this->appkey));
		return $this->read();
	}

	public function delete_queue($queue_name){
		$this->send("DELETE", array('queue_name'=>$queue_name, 'appkey'=>$this->appkey));
		return $this->read();
	}

	public function clear_queue($queue_name){
		$this->send("CLEAR", array('queue_name'=>$queue_name, 'appkey'=>$this->appkey));
		return $this->read();
	}

	public function put_queue($queue_name, $data){
		if(is_array($data) || is_object($data)) $data = serialize($data);

		$this->send("PUT", array('queue_name'=>$queue_name, 'data'=>$data, 'appkey'=>$this->appkey));
		return $this->read();
	}

	public function get_queue($queue_name){
		$this->send("GET", array('queue_name'=>$queue_name, 'appkey'=>$this->appkey));
		return $this->read();
	}

	public function state($queue_name){
		$this->send("STATE", array('queue_name'=>$queue_name, 'appkey'=>$this->appkey));
		return $this->read();
	}
}

$queue_client = new QueueClient("localhost", 8080, 'testkey');

//test create queue
$result = $queue_client->create_new_queue("test_queue", 10000);
print_r($result);

//test put
for($i=0; $i<100; $i++){
	$result = $queue_client->put_queue("test_queue", "jinyong");
	print_r($result);
}

// test get_queue
for($i=0; $i<100; $i++){
	$result = $queue_client->get_queue("test_queue");
	print_r($result);
}

// test state_queue
$result = $queue_client->state("test_queue");
print_r($result);

// test clear_queue
$queue_client->clear_queue("test_queue");

下面是客户端请求结果的部分截图:



队列服务器软件下载:http://yunpan.cn/QWsgA3iYXXZ5A

队列服务器源码、PHP客户端源码下载:http://yunpan.cn/QWsgy2UU5NhSE

作者:a600423444 发表于2013-4-17 1:21:58 原文链接
阅读:131 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>