应用服务队列开发

看了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]  view plain copy
  1. <?php  
  2. define('QUEUE_MAX_LENGTH', 10000);  
  3.   
  4. class QueueSocket{  
  5.     private $socket;  
  6.     private $errmsg;  
  7.   
  8.     public function __construct($host$port){  
  9.         $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);  
  10.         socket_bind($this->socket, $host);  
  11.         if(!socket_connect($this->socket, $host$port)){  
  12.             $this->set_errmsg("Unable to connect<pre>".socket_strerror(socket_last_error())."</pre>");  
  13.             return false;  
  14.         }  
  15.   
  16.         return true;  
  17.     }  
  18.   
  19.     public function send($cmd$content){  
  20.         if(!is_array($content) || !$content) {  
  21.             return false;  
  22.         }  
  23.   
  24.         $params = false;  
  25.         foreach($content as $key=>$value){  
  26.             $params[] = strtoupper($key)."={$value}";  
  27.         }  
  28.   
  29.         $params = join('&'$params)."\r\n";  
  30.         $binary = pack("a20i1a*"strtoupper($cmd), strlen($params), $params);  
  31.   
  32.         socket_write($this->socket, $binarystrlen($binary));  
  33.     }  
  34.   
  35.     public function read(){  
  36.         $response = socket_read($this->socket, 256, PHP_BINARY_READ);  
  37.   
  38.         if($response) {  
  39.             $response = json_decode($response, true);  
  40.         }else{  
  41.             return false;  
  42.         }  
  43.   
  44.         if(isset($response['errno']) && $response['errno'] > 0)   
  45.             $this->set_errmsg($response['errmsg']);  
  46.   
  47.         return $response;  
  48.     }  
  49.   
  50.     public function set_errmsg($msg){  
  51.         $this->errmsg = $msg;  
  52.     }  
  53.   
  54.     public function get_errmsg(){  
  55.         return $this->errmsg;  
  56.     }  
  57.   
  58.     public function __destory(){  
  59.         socket_close($this->socket);  
  60.     }  
  61. }  
  62.   
  63. class QueueClient extends QueueSocket{  
  64.     private $appkey;  
  65.   
  66.     public function __construct($host$port$appkey){  
  67.         $this->appkey = $appkey;  
  68.         parent::__construct($host$port);  
  69.     }  
  70.   
  71.     public function create_new_queue($queue_name$max_length = QUEUE_MAX_LENGTH){  
  72.         $this->send("CREATE"array('queue_name'=>$queue_name'max_length'=>$max_length'appkey'=>$this->appkey));  
  73.         return $this->read();  
  74.     }  
  75.   
  76.     public function delete_queue($queue_name){  
  77.         $this->send("DELETE"array('queue_name'=>$queue_name'appkey'=>$this->appkey));  
  78.         return $this->read();  
  79.     }  
  80.   
  81.     public function clear_queue($queue_name){  
  82.         $this->send("CLEAR"array('queue_name'=>$queue_name'appkey'=>$this->appkey));  
  83.         return $this->read();  
  84.     }  
  85.   
  86.     public function put_queue($queue_name$data){  
  87.         if(is_array($data) || is_object($data)) $data = serialize($data);  
  88.   
  89.         $this->send("PUT"array('queue_name'=>$queue_name'data'=>$data'appkey'=>$this->appkey));  
  90.         return $this->read();  
  91.     }  
  92.   
  93.     public function get_queue($queue_name){  
  94.         $this->send("GET"array('queue_name'=>$queue_name'appkey'=>$this->appkey));  
  95.         return $this->read();  
  96.     }  
  97.   
  98.     public function state($queue_name){  
  99.         $this->send("STATE"array('queue_name'=>$queue_name'appkey'=>$this->appkey));  
  100.         return $this->read();  
  101.     }  
  102. }  
  103.   
  104. $queue_client = new QueueClient("localhost", 8080, 'testkey');  
  105.   
  106. //test create queue  
  107. $result = $queue_client->create_new_queue("test_queue", 10000);  
  108. print_r($result);  
  109.   
  110. //test put  
  111. for($i=0; $i<100; $i++){  
  112.     $result = $queue_client->put_queue("test_queue""jinyong");  
  113.     print_r($result);  
  114. }  
  115.   
  116. // test get_queue  
  117. for($i=0; $i<100; $i++){  
  118.     $result = $queue_client->get_queue("test_queue");  
  119.     print_r($result);  
  120. }  
  121.   
  122. // test state_queue  
  123. $result = $queue_client->state("test_queue");  
  124. print_r($result);  
  125.   
  126. // test clear_queue  
  127. $queue_client->clear_queue("test_queue");  

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



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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值