设为首页| 加入收藏| 投稿建议    

PHP fsockopen异步调用出现不执行的问题

发表于2016-11-06 11:40:32| 135次阅读| 0 条评论| 作者AndyYang

摘要:因为项目出现一个异步调用的场景,即有些动作需要执行,但没必要等待其执行完返回结果。所以想通过php来模拟下异步调用(众所周知:php在异步调用就是鸡肘),之前用curl实现过,现在想用fsockopen来尝试下。
因为项目出现一个异步调用的场景,即有些动作需要执行,但没必要等待其执行完返回结果。所以想通过php来模拟下异步调用(众所周知:php在异步调用就是鸡肘),之前用curl实现过,现在想用fsockopen来尝试下。

function doSocket($get){
    $url = "http://www.webyang.net";
    $fp = fsockopen($url, 80, $errno, $errstr, 30);
    if (!$fp) {
        echo "$errstr ($errno)<br />\n";
    } else {
        $out = "GET /".$get." HTTP/1.1\r\n";
        $out .= "Host: ".$url."\r\n";
        $out .= "Connection: Close\r\n\r\n";
     
        fwrite($fp, $out);
        /*忽略执行结果
        while (!feof($fp)) {
            echo fgets($fp, 128);
        }*/
        fclose($fp);
    }
}
这样执行的时候,结果发现很多丢失,并没有处理。网上查了下,发现很多这种情况。看了下access.log文件,http的状态是499(client has closed connection)。和这篇文章:www.cnblogs.com/zhangweishi/p/5306813.html 很类似。

于是将此方法做了调整:
function doSocket($get){
    $url = "http://www.webyang.net";
    $fp = fsockopen($url, 80, $errno, $errstr, 30);
    if (!$fp) {
        echo "$errstr ($errno)<br />\n";
    } else {
        stream_set_blocking($fp,0); //开启非阻塞模式
        stream_set_timeout($fp, 3); //设置超时时间(s)

        $out = "GET /".$get." HTTP/1.1\r\n";
        $out .= "Host: ".$url."\r\n";
        $out .= "Connection: Close\r\n\r\n";
     
        fwrite($fp, $out);
        usleep(300000); //等待300ms

        /*忽略执行结果
        while (!feof($fp)) {
            echo fgets($fp, 128);
        }*/
        fclose($fp);
    }
}
并且在异步脚本的头部添加了:
ignore_user_abort (true);
set_time_limit (30);
观察了一段时间,没发现啥异样。
要解决这个问题需要将 NGINX FastCGI 忽略客户端中断配置打开:

如果是服务器(fastcgi)的话,可以尝试下:
fastcgi_ignore_client_abort on;
不过这个可能给服务器带来没必要的开销,和意想不到的其他问题。

有兴趣的可以研究下:swooleworkerman

如果您觉得好,可以打赏作者:

已有0条评论

昵称:
邮箱:

  • 最新评论

反馈
微信订阅号