2.0 php写的服务器,升级版本

2.0 php写的服务器,升级版本
支持信号处理
使用的是epoll io复用模型事件监听。

<?php
/**
 * Created by PhpStorm.
 * User: Sixstar-Peter
 * Date: 2018/11/14
 * Time: 21:04
 */

class Server{
    private  $_mainSocket;
    private  $_newSocket;
    private  $_EventBase;
    public   $pids;
    public  function  __construct()
    {
        //从配置文件
        $this->forkServer(); //创建服务监听
        file_put_contents('/tmp/master.pid',getmypid());  //
    }

    public function signalHandler($signo){
        switch ($signo) {
            case SIGTERM:
                echo 'kill';
                exit;
                break;
            case SIGHUP:
                //处理SIGHUP信号
                break;
            case SIGINT:
                //处理ctrl+c
                echo 'ctrl+c';
                exit;
                break;
            default:
                // 处理所有其他信号
        }
    }
   protected function  monitor(){
            //SIGINT ctrl+c
          //注册信号处理器,信号信号触发时,执行的闭包(进程关闭之后,回收主进程的pid文件)
          pcntl_signal(SIGINT,[$this,'signalHandler']);
          pcntl_signal(SIGTERM,[$this,'signalHandler']);

          while (1){
              pcntl_signal_dispatch(); //调用等待信号的处理器,触发信号事件,挂起状态
              $pid=pcntl_wait($status,WUNTRACED); //等待子进程中断,防止子进程成为僵尸进程。
              $status=0;
         }

    }


    public  function  forkServer($count=2){
        for ($i = 0; $i < $count; ++$i)
        {
            $pid = pcntl_fork();
            if ($pid < 0) {
                exit('生成子进程失败\n');
            } else if ($pid > 0) {
                // 父进程
                $this->pids[] = $pid;
            } else {
                $this->listen();
                exit;
            }
        }
        $this->monitor(); //监视

    }

    public  function  listen (){
        $tcp    = "0.0.0.0:9005";

        // 创建资源流上下文
        $context = stream_context_create([
            'socket' => [
                'backlog' => 102400
            ]
        ]);
        //监听客户端链接 + 设置端口重用
        stream_context_set_option($context , 'socket' , 'so_reuseport' , 1);
        stream_context_set_option($context,'socket','so_reuseaddr',1); //设置连接重用

        $this->_mainSocket = stream_socket_server($tcp , $errno , $errstr , STREAM_SERVER_BIND | STREAM_SERVER_LISTEN , $context);
        stream_set_blocking($this->_mainSocket , false);

        $this->_EventBase = new \EventBase();
        $event=new \Event( $this->_EventBase,$this->_mainSocket,Event::READ | Event::PERSIST,function (){
            $this->_newSocket = stream_socket_accept($this->_mainSocket);
            stream_set_blocking($this->_newSocket , false);//非阻塞

            //触发客户端事件
            $event=new \Event( $this->_EventBase , $this->_newSocket , Event::READ | Event::PERSIST  ,function($socket)use(&$event){
                $msg = fread($socket , 65535);
                // Check connection closed.检查连接是否关闭
                if ($msg === '') {

                    if ((feof($socket) || !is_resource($socket))) {
                        $event->del(); //删除事件
                        return null;
                    }
                }else{
                    $content = '<p>我是需要访问的内容</p>';
                    $header = "HTTP/1.1 200 OK\r\n";
                    $header .= "Content-Type: text/html;charset=utf-8\r\n";
                    $header .= "Connection: keep-alive\r\n";
                    $header .= "Content-Length: " . strlen($content) . "\r\n\r\n";
                    fwrite($socket,$header . $content);
                }
            },$this->_newSocket);
            $event->add(); //挂起事件
        });
        $event->add();
        $this->_EventBase->loop();

    }

}

$server=new Server();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿威,awin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值