PHP異步非阻塞fsockopen(本地能夠非阻塞請求,服務器就一直執行異步的不成功) (未解決)

index.phpphp

    /**
     * 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\r\n";
        $header .= "Host: ".$url_arr['host']."\r\n";

        if(!empty($cookie)){  //傳遞cookie信息
            $_cookie = strval(NULL);
            foreach($cookie AS $k=>$v){
                $_cookie .= $k."=".$v.";";
            }
            $cookie_str = "Cookie:".base64_encode($_cookie)."\r\n";
            $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\r\n";
            $post_str .= "Content-Length: ".strlen($_post)."\r\n";  //數據長度
            $post_str .= "Connection:Close\r\n\r\n";
            $post_str .= $_post;  //傳遞post數據
            $header .= $post_str;
        }else{
            $header .= "Connection:Close\r\n\r\n";
        }
        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.phphtml

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

 

這段代碼:nginx

本地不用等待,而且1.php能夠請求帶 (本地環境win7+php7.1.13和apache (CGI/FastCGI))web

可是放到服務端:不用等待,可是1.php不能被請求到。(服務器環境win2016+php7.1.13和apache (CGI/FastCGI),寶塔集成的環境)apache

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

 

經過上面的描述,能夠判斷,應該請求能夠發送到服務器,可是服務器沒有處理或沒有處理成功,沒有響應.服務器

(其實最終處理方法,要看服務器請求日誌,看請求返回碼對應處理,當時沒想到~)cookie

 經過查資料:php7

1.fsockopen,能夠設置阻塞和非阻塞請求 https://www.php.net/manual/zh/function.fsockopen.phpapp

設置: 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

相關文章
相關標籤/搜索