php cli编写一个高并发的http服务
大家都知道php的http请求处理脚本是运行在apache或php-fpm中,那么除此之外还有其他吗?有,其实php cli命令行中也是可以响应http请求并处理的,最简单的参照对象就是workman、swoole,php可以监听tcp或udp的端口,实现http协议,今天我们来试一试
<?php $socket = stream_socket_server("0.0.0.0:8889", $errno, $errstr); stream_set_blocking($socket, 0);//设置是否阻塞 if (!$socket) { echo "$errstr ($errno)<br />\n"; } else { while (true) { $conn = @stream_socket_accept($socket);//接受客户端的请求 if ($conn) { fwrite($conn, '当前时间是 ' . date('n/j/Y g:i a') . "\n");//响应客户端请求 fclose($conn); } else { echo "no newSocket\n"; } } } ?>上面面是个简单的http监听服务,具体的post、session等处理还需有更进一步的优化,好了,有的人肯定好奇,就这么几句话就实现高并发了?
没那么简单,高并发还需要多个进程来进行处理,php-fpm也不止一个呀,好了,我们来写一个Worker,实现进程自我创建和管理,提高php的并发处理能力,就想餐馆,一个服务员不够就多个嘛
<?php class Worker { /** * version * @var string */ const VERSION = '0.0.1'; /** * Emitted when data is received * @var callable */ public $onMessage = NULL; /** * 子进程的数量 * @var int */ public $count = 1; /** * Listening socket * @var resource */ public $socket = NULL; /** * Socket name The format is like this 0.0.0.0:8000 * @var string */ protected $_socketName = ''; /** * 连接socket * @var resource */ protected $_connSocket = NULL; /** * 子进程 pid 数组 * @var array */ private $forkList = []; /** * 主进程 ID 文件 * @var string */ private $masterPidFile = 'master.pid'; /** * 主进程是否停止 * @var int */ private $masterStop = 0; public function __construct($socketName, $options = []) { $this->_socketName = $socketName; } public function init() { $this->parseCommand(); } public function start() { // 判断当前程序是否已经启动 $masterPidFileExist = is_file($this->masterPidFile); if ($masterPidFileExist) { exit("当前程序已经在运行,请不要重启启动 "); } // 保存主进程pid到文件用于stop,reload,status等命令操作 $masterPid = posix_getpid(); file_put_contents($this->masterPidFile, $masterPid); pcntl_signal(SIGINT, array($this, 'signalHandler'), false); pcntl_signal(SIGTERM, array($this, 'signalHandler'), false); pcntl_signal(SIGUSR1, array($this, 'signalHandler'), false); $this->listen(); // 创建count个子进程,用于接受请求和处理数据 while(count($this->forkList) < $this->count) { $this->forkWokrer(); } while (true) { //sleep(1); pcntl_signal_dispatch(); // 信号分发 $status = 0; $pid = pcntl_wait($status, WUNTRACED); // 堵塞直至获取子进程退出或中断信号或调用一个信号处理器,或者没有子进程时返回错误 p...
点击查看剩余70%
网友评论0