zoukankan      html  css  js  c++  java
  • PHP异步请求之fsockopen()方法详解

    正常情况下,PHP执行的都是同步请求,代码自上而下依次执行,但有些场景如发送邮件、执行耗时任务等操作时就不适用于同步请求,只能使用异步处理请求。

    场景要求:

    客户端调用服务器a.php接口,需要执行一个长达10s-20s不等的耗资源操作,假如客户端响应请求时间为5秒(请求响应超时时间),5s以上无回复即断开连接。

    解决设想:

    客户端调用a.php之后,a.php执行异步多线程操作调用b.php,a.php调用成功后即刻反馈给客户端回执,b.php自动执行耗资源操作。

    方案:

    利用fsockopen()方法解决PHP异步请求

    1.封装异步请求函数asyncRequest(),代码如下:

    /**
         * php异步请求
         * @param $host string 主机地址
         * @param $path string 路径
         * @param $param array 请求参数
         * @return string
         */
        private static function asyncRequest($host, $path, $param = array()){
    
            $query = isset($param) ? http_build_query($param) : '';
            Bd_Log::debug($query);
            $port = 80;
            $errno = 0;
            $errstr = '';
            $timeout = 30; //连接超时时间(S)
    
            $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
            //$fp = stream_socket_client("tcp://".$host.":".$port, $errno, $errstr, $timeout);
    
            if (!$fp) {
    
                Bd_Log::debug('连接失败');
                return '连接失败';
            }
            if ($errno || !$fp) {
    
                Bd_Log::debug($errstr);
                return $errstr;
            }
    
            stream_set_blocking($fp,0); //非阻塞
            stream_set_timeout($fp, 1);//响应超时时间(S)
            $out  = "POST " . $path . " HTTP/1.1
    ";
            $out .= "host:" . $host . "
    ";
            $out .= "content-length:" . strlen($query) . "
    ";
            $out .= "content-type:application/x-www-form-urlencoded
    ";
            $out .= "connection:close
    
    ";
            $out .= $query;
    
            $result = @fputs($fp, $out);
    
            @fclose($fp);
            return $result;
    
        }

    实例:

    正常接口a.php,如下

        /**
         * 正常接口a.php
         * @param $host string 主机地址
         * @param $path string 路径
         * @param $param array 请求参数
        */
      public function a(){
           $param = array(
               'XXX' => $XXX,
            );
            $asyncData = $this->asyncRequest( $host, $path ,$param);
    
            echo'a.php success'      
      }

    耗时接口b.php,如下

        /**
         * 耗时接口b.php,依次输出三种结果
        */
        public function b(){
        
          set_time_limit(0);
            ignore_user_abort(true);//设置与客户机断开是否会终止执行
            fastcgi_finish_request();//提高请求的处理速度
      
            sleep(30);
            echo "耗时30秒";
    
            sleep(20);
            echo "耗时20秒";
    
            sleep(10);
            echo "耗时10秒";
        }

    上述实例即为简单的测试接口部分代码,根据自己需求做修改即可;

  • 相关阅读:
    [题解] P2513 [HAOI2009]逆序对数列
    [题解]洛谷P2709 小B的询问
    题解 P1944 最长括号匹配_NOI导刊2009提高(1)
    [题解]SP703 SERVICE
    Bzoj2427: [HAOI2010]软件安装
    【题解】UVA11362 Phone List
    【题解】P2922 [USACO08DEC]秘密消息Secret Message
    Tire树的学习
    【题解】P1171 售货员的难题
    计算机与编程资源教程汇总
  • 原文地址:https://www.cnblogs.com/wenzheshen/p/10213480.html
Copyright © 2011-2022 走看看