PHP写的异步高并发服务器,基于libevent

时间:2022-04-11 00:13:14

PHP写的异步高并发服务器,基于libevent

博客分类: PHPFPSocketLinuxQQ 

本文章于2013年11月修改。

swoole已使用C重写作为PHP扩展来运行。项目地址:https://github.com/matyhtf/swoole

swoole提供了PHP的高性能Server,异步IO,AsyncMySQL等特性。

 

原PHP代码框架迁移至https://github.com/matyhtf/swoole_framework。保留原有代码和web框架。

--------------------------------------------------------------------------------------------------

 

Swoole Socket网络开发框架,是基于php的libevent和pcntl模块的,并且只能用于Linux/Unix系统下。请先启用pcntl,安装libevent扩展。

pcntl:PHP核心模块已包含了pcntl,只需在编译时加入--enable-pcntl即可,当然也可以用extension扩展

libevent:http://pecl.php.net/package/libevent

编写的类需要继承自TCPServer类,在SwooleSocket包中。目前只提供了单进程异步事件模型,适合用于IO耗时较少的网络服务器程序,比如聊天室。多进程异步模型,多进程同步模型,会在近期提供。基类的代码,请从http://code.google.com/p/swoole/检出

 

Php代码  PHP写的异步高并发服务器,基于libevent
  1. <?php  
  2. require 'TCPServer.php';  
  3.   
  4. class MyServer extends TCPServer  
  5. {  
  6.     function onRecive($client_id,$data)  
  7.     {  
  8.         $data = trim($data);  
  9.         if($data=="quit")  
  10.         {  
  11.             $this->close($client_id);  
  12.             return true;  
  13.         }  
  14.         elseif($data=='shutdown')  
  15.         {  
  16.             $this->shutdown();  
  17.         }  
  18.         else  
  19.         {  
  20.             $client_socket_name =  stream_socket_get_name($this->client_sock[$client_id],true);  
  21.             echo "Server send response data to client $client_socket_name\n";  
  22.             $send = date('Y-m-d H:i:s')."$client_socket_name said:$data\n";  
  23.             $this->sendAll($client_id,$send);  
  24.         }  
  25.     }  
  26.     /** 
  27.      * 发送到所有客户端 
  28.      * @param $data 
  29.      * @return unknown_type 
  30.      */  
  31.     function sendAll($client_id,$data)  
  32.     {  
  33.         foreach($this->client_sock as $k=>$sock)  
  34.         {  
  35.             if($k==$client_id) continue;  
  36.             fwrite($sock,$data);  
  37.         }  
  38.     }  
  39.     /** 
  40.      * 发送到某个客户端 
  41.      * @param $client_id 
  42.      * @param $data 
  43.      * @return unknown_type 
  44.      */  
  45.     function sendTo($client_id,$data)  
  46.     {  
  47.         fwrite($this->client_sock[$client_id],$data);  
  48.     }  
  49.   
  50.     function onStart()  
  51.     {  
  52.         echo "Server in running!\n";  
  53.     }  
  54.   
  55.     function onConnect($client_id)  
  56.     {  
  57.         $this->sendAll($client_id,"Client $client_id is connected!\n");  
  58.     }  
  59.   
  60.     function onClose($client_id)  
  61.     {  
  62.         $this->sendAll($client_id,"Client $client_id is closed!\n");  
  63.     }  
  64.   
  65.     function onShutdown()  
  66.     {  
  67.         echo "Server in stop!\n";  
  68.     }  
  69. }  
  70.   
  71. $server = new MyServer('0.0.0.0',8005);  
  72. $server->run();  

 

 

客户端程序

 

 

Php代码  PHP写的异步高并发服务器,基于libevent
  1. <?php  
  2. class Stdio  
  3. {  
  4.     static $in;  
  5.     static $out;  
  6.     static $buffer_size = 1024;  
  7.   
  8.     static function input($h='')  
  9.     {  
  10.         if(!self::$in) self::$in = fopen('php://stdin','r');  
  11.         if($h) self::output($h);  
  12.         return trim(fread(self::$in,self::$buffer_size));  
  13.     }  
  14.     static function output($string)  
  15.     {  
  16.         if(!self::$out) self::$out = fopen('php://stdout','w');  
  17.         return fwrite(self::$out,$string);  
  18.     }  
  19. }  
  20.   
  21. $fp = stream_socket_client('tcp://127.0.0.1:8005',$errno, $errstr);  
  22. $socket = serialize($fp);  
  23. if(!$fp)  
  24. {  
  25.     echo "ERROR: $errno - $errstr<br />\n";  
  26. }  
  27. else  
  28. {  
  29.     $pid = pcntl_fork();  
  30.     if($pid==-1)  
  31.     {  
  32.         exit("fork fail!\n");  
  33.     }  
  34.     //child  
  35.     elseif($pid==0)  
  36.     {  
  37.         var_dump($socket);  
  38.         $fp2 = unserialize($socket);  
  39.         while(!feof($fp2))  
  40.         {  
  41.             Stdio::output(fgets($fp2, 1024));  
  42.         }  
  43.     }  
  44.     //parent  
  45.     else  
  46.     {  
  47.         while($string!=="quit")  
  48.         {  
  49.             if(!is_writable($fp)) break;  
  50.             $string = Stdio::input("qq#");  
  51.             fwrite($fp,$string);  
  52.         }  
  53.         posix_kill($pid, 9);  
  54.     }  
  55.     fclose($fp);  
  56. }  

php tcpserver.php 运行服务器程序

php tcpclient.php 运行客户端程序,客户端有2个进程,主进程负责接收输入信息,发送到网络。另一个进程,接收网络信息,显示在屏幕上。