• PHP异步非阻塞fsockopen(本地可以非阻塞请求,服务器就一直执行异步的不成功) (未解决)


    index.php

        /**
         * php异步请求
         *
         * @param $host string 主机地址
         * @param $path string 路径
         * @param $param array 请求参数
         * @return string
         */
    function asyncRequest($url,$post_data=array(),$cookie=array())
        {
            $url_arr = parse_url($url);
            $port = isset($url_arr['port'])?$url_arr['port']:80;
    
            if($url_arr['scheme'] == 'https'){
                $url_arr['host'] = 'ssl://'.$url_arr['host'];
            }
            $fp = fsockopen($url_arr['host'],$port,$errno,$errstr,30);
            if(!$fp) return false;
            $getPath = isset($url_arr['path'])?$url_arr['path']:'/index.php';
            $getPath .= isset($url_arr['query'])?'?'.$url_arr['query']:'';
            $method = 'GET';  //默认get方式
            if(!empty($post_data)) $method = 'POST';
            $header = "$method  $getPath  HTTP/1.1
    ";
            $header .= "Host: ".$url_arr['host']."
    ";
    
            if(!empty($cookie)){  //传递cookie信息
                $_cookie = strval(NULL);
                foreach($cookie AS $k=>$v){
                    $_cookie .= $k."=".$v.";";
                }
                $cookie_str = "Cookie:".base64_encode($_cookie)."
    ";
                $header .= $cookie_str;
            }
    
            if(!empty($post_data)){  //传递post数据
                $_post = array();
                foreach($post_data AS $_k=>$_v){
                    $_post[] = $_k."=".urlencode($_v);
                }
                $_post = implode('&', $_post);
                $post_str = "Content-Type:application/x-www-form-urlencoded; charset=UTF-8
    ";
                $post_str .= "Content-Length: ".strlen($_post)."
    ";  //数据长度
                $post_str .= "Connection:Close
    
    ";
                $post_str .= $_post;  //传递post数据
                $header .= $post_str;
            }else{
                $header .= "Connection:Close
    
    ";
            }
            fwrite($fp, $header);
            usleep(1000); // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功
            fclose($fp);
            return true;
        }
    
    
    
    
            //$url = 'http://xxx.com/1.php';
            $url = 'http://localhost/1.php';
            $res = asyncRequest($url);
            var_dump($res);
            echo "我没有等a站点返回值,我就执行了";

    1.php

    sleep(3);
    file_put_contents("1234.txt",time(),FILE_APPEND);

    这段代码:

    本地不用等待,并且1.php可以请求带 (本地环境win7+php7.1.13和apache (CGI/FastCGI))

    但是放到服务端:不用等待,但是1.php不能被请求到。(服务器环境win2016+php7.1.13和apache (CGI/FastCGI),宝塔集成的环境)

    奇怪的是,本地 asyncRequest() 本地1.php,成功,  本地asyncRequest()服务器的1.php,不成功

    通过上面的描述,可以判断,应该请求可以发送到服务器,但是服务器没有处理或没有处理成功,没有响应.

    (其实最终处理方法,要看服务器请求日志,看请求返回码对应处理,当时没想到~)

     通过查资料:

    1.fsockopen,可以设置阻塞和非阻塞请求 https://www.php.net/manual/zh/function.fsockopen.php

    设置: stream_set_blocking()

    2.一种可能性是: FastCGI 客户端中断时,服务器会立马停止处理,(其实这种情况在日志里面http的状态是499(client has closed connection))

    http://www.webyang.net/Html/web/article_281.html

    需要,设置异步程序,客户端断开继续执行,和超时时间, 好像nginx+php-fpm要配置 fastcgi_ignore_client_abort on

    ignore_user_abort (true);
    set_time_limit (30);

    3.这个错误是我看日志的到的,我发现fsockopen请求的网页,http状态码是400错误,查了下400是请求头错误,那应该是asyncRequest()函数封装http头信息错误,(为什么本地环境没报400错误,服务器环境报400错误),我也没搞清,估计配置不一样

     我例子里面的 GET  /1.php   HTTP/1.1 都是两个空格

     最后删了多余的空格,改了请求头好了!!!

    查的一些参考:

    https://www.awaimai.com/660.html

    https://blog.csdn.net/weixin_33690367/article/details/91689736

    https://zhidao.baidu.com/question/2267107086723350868.html

    https://segmentfault.com/q/1010000012574466/a-1020000012583303

     http://www.webyang.net/Html/web/article_281.html

  • 相关阅读:
    Git 基本操作
    Git 基础
    MarkDown教程
    Python常用函数
    Python生成器
    Python列表生成式
    Python迭代
    Python切片
    Python函数
    Python不可变对象
  • 原文地址:https://www.cnblogs.com/fps2tao/p/11677667.html
Copyright © 2020-2023  润新知