当前位置 主页 > 服务器问题 > win服务器问题汇总 >

    php实现的简单多进程服务器类完整示例

    栏目:win服务器问题汇总 时间:2020-02-04 10:55

    本文实例讲述了php实现的简单多进程服务器类。分享给大家供大家参考,具体如下:

    php写的一个简单的多进程服务器。

    <?php
    class server
    {
      public $port;
      public $ip;
      protected $server;
      public function __construct($ip = '0.0.0.0', $port)
      {
        $this->ip = $ip;
        $this->port = $port;
        $this->createSocket(); //创建一个通讯节点
      }
      public function listen($callback)
      {
        if(!is_callable($callback)){
          throw new Exception('不是闭包,请传递正确的参数');
        }
        //只要我们接收到客户端的数据,就fork一个子进程处理
        while ($client = socket_accept($this->server)) { //等待客户端接入,返回的是客户端的连接
          $buf = socket_read($client, 1024); //读取客户端内容
          $pid=pcntl_fork(); //创建子进程
          //父进程和子进程都会执行下面代码
          if ($pid == -1) {
            //错误处理:创建子进程失败时返回-1.
            die('could not fork');
          } else if ($pid) {
            //父进程会得到子进程号,所以这里是父进程执行的逻辑
            var_dump('父进程',$pid);
            pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
          } else {
            //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
            //睡眠
            if($this->checkRule("/sleep/i",$buf)){
              sleep(10);
              $this->response('休眠10S',$client);
              socket_close($client);
              return;
            }
            //请求过滤
            if(empty($this->checkRule("/GET\s(.*?)\sHTTP\/1.1/i",$buf))){
              socket_close($client);
              return;
            }
            //响应
            $response= call_user_func($callback,$buf); //回调$callback函数
            $this->response($response,$client);
            usleep(1000); //微妙为单位,1000000 微妙等于1秒
            socket_close($client);
            exit(); //直接退出
          }
        }
    //    while (true) {
    //      $client = socket_accept($this->server); //等待客户端接入,返回的是客户端的连接
    //      $buf = socket_read($client, 1024); //读取客户端内容
    //
    //      //睡眠
    //      if($this->checkRule("/sleep/i",$buf)){
    //        sleep(10);
    //        $this->response('休眠10S',$client);
    //        socket_close($client);
    //        return;
    //      }
    //      //请求过滤
    //      if(empty($this->checkRule("/GET\s(.*?)\sHTTP\/1.1/i",$buf))){
    //        socket_close($client);
    //        return;
    //      }
    //
    //      //响应
    //      $response= call_user_func($callback,$buf); //回调$callback函数
    //      $this->response($response,$client);
    //      usleep(1000); //微妙为单位,1000000 微妙等于1秒
    //      socket_close($client);
    //
    //    }
        socket_close($this->server);
      }
      //io 复用
      //epoll 模型
      //多进程
      protected function createSocket()
      {
        $this->server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        //bind
        socket_set_option($this->server, SOL_SOCKET, SO_REUSEADDR, 1); //复用还处于 TIME_WAIT
        socket_bind($this->server, $this->ip, $this->port); //细节性的处理自行完成
        socket_listen($this->server); //开始监听
      }
      /**
       * 协议过滤
       * @param $reg
       * @param $buf
       * @return mixed
       */
      protected function checkRule($reg,$buf){
        if(preg_match($reg,$buf,$matchs)){
          return $matchs;
        }
        return false;
      }
      //请求处理类
      public function request($buf){
        //1.只允许http协议访问
    //    if(preg_match("GET\s(.*?)\sHTTP/1.1",$buf,$matchs)){ //匹配到http协议
    //      return true;
    //    }else{
    //      return false;
    //    }
        //2.过滤掉/favicon.ico
        //3.获取请求信息
      }
      protected function response($content,$client){
        //返回数据给客户端,响应处理
        $string="HTTP/1.1 200 OK\r\n";
        $string.="Content-Type: text/html;charset=utf-8\r\n";
        $string.="Content-Length: ".strlen($content)."\r\n\r\n";
        socket_write($client,$string.$content);
      }
    }