您的位置 首页 php

php中使用fsockopen实现异步请求(代码示例)

php中使用fsockopen实现异步请求(代码示例)

php执行一段程序,有可能几毫秒就执行完毕,也有可能耗时较长。

例如,用户下单这个事件,如果调用了些第三方服务进行发邮件、短信、推送等通知,可能导致前端一直在等待。

而有的时候,我们并不关心这些耗时脚本的返回结果,只要执行就行了。这时候就需要采用异步的方式执行。

众所周知,PHP没有直接支持多线程这种东西。我们可以采用折衷的方式实现。这里主要说的就是fsockopen

通过fsockopen发送请求并忽略返回结果,程序可以马上返回。

示例代码:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);if (!$fp) {    echo "$errstr ($errno)<br />n";} else {    $out = "GET /backend.php   HTTP/1.1rn";    $out .= "Host: www.example.comrn";    $out .= "Connection: Closernrn";     fwrite($fp, $out);    /*忽略执行结果    while (!feof($fp)) {        echo fgets($fp, 128);    }*/    fclose($fp);}

需要注意的是我们需要手动拼出header头信息。通过打开注释部分,可以查看请求返回结果,但这时候又变成同步的了,因为程序会等待返回结果才结束。

实际测试的时候发现,不忽略执行结果,调试的时候每次都会成功发送sock请求;但忽略执行结果,经常看到没有成功发送sock请求。查看nginx日志,发现很多状态码为499的请求。

后来找到了原因:

fwrite之后马上执行fclose,nginx会直接返回499,不会把请求转发给php处理。

客户端主动端口请求连接时,NGINX 不会将该请求代理给上游服务(FastCGI PHP 进程),这个时候 access log 中会以 499 记录这个请求。

解决方案:

1)nginx.conf增加配置

# 忽略客户端中断fastcgi_ignore_client_abort on;

2)fwrite之后使用usleep函数休眠20毫秒:

usleep(20000);

后来测试就没有发现失败的情况了。

附上完整代码:

<?php/** * 工具类 * */class FsockService {        public static function post($url, $param){        $host = parse_url($url, PHP_URL_HOST);        $port = 80;        $errno = '';        $errstr = '';        $timeout = 30;        $data = http_build_query($param);        // create connect        $fp = fsockopen($host, $port, $errno, $errstr, $timeout);        if(!$fp){            return false;        }        // send request        $out = "POST ${url} HTTP/1.1rn";        $out .= "Host:${host}rn";        $out .= "Content-type:application/x-www-form-urlencodedrn";        $out .= "Content-length:".strlen($data)."rn";        $out .= "Connection:closernrn";        $out .= "${data}";        fwrite($fp, $out);        //忽略执行结果;否则等待返回结果//        if(APP_DEBUG === true){        if(false){            $ret = '';            while (!feof($fp)) {                $ret .= fgets($fp, 128);            }        }        usleep(20000); //fwrite之后马上执行fclose,nginx会直接返回499        fclose($fp);    }    public static function get($url, $param){        $host = parse_url($url, PHP_URL_HOST);        $port = 80;        $errno = '';        $errstr = '';        $timeout = 30;        $url = $url.'?'.http_build_query($param);        // create connect        $fp = fsockopen($host, $port, $errno, $errstr, $timeout);        if(!$fp){            return false;        }        // send request        $out = "GET ${url} HTTP/1.1rn";        $out .= "Host:${host}rn";        $out .= "Connection:closernrn";        fwrite($fp, $out);        //忽略执行结果;否则等待返回结果//        if(APP_DEBUG === true){        if(false){            $ret = '';            while (!feof($fp)) {                $ret .= fgets($fp, 128);            }        }        usleep(20000); //fwrite之后马上执行fclose,nginx会直接返回499        fclose($fp);    }   }?>

更多相关php知识,请访问php教程!

以上就是php中使用fsockopen实现异步请求(代码示例)的详细内容,更多请关注求知技术网其它相关文章!

文章来源:智云一二三科技

文章标题:php中使用fsockopen实现异步请求(代码示例)

文章地址:https://www.zhihuclub.com/2078.shtml

关于作者: 智云科技

热门文章

评论已关闭

6条评论

  1. What’s up to every single one, it’s in fact a nice for me to
    visit this site, it includes precious Information.

  2. After controlling for age, race, income, and Charlson Comorbidity Index, women with bilateral salpingo oophorectomy had a 14 lower risk of breast cancer than women with hysterectomy alone hazard ratio, 0

  3. What’s Happening i’m new to this, I stumbled upon this I’ve found It positively useful and it
    has aided me out loads. I’m hoping to give a contribution & help
    different customers like its helped me. Good job.

  4. What’s up to every body, it’s my first pay a
    quick visit of this web site; this web site contains awesome and actually fine information for readers.

  5. I visited many web sites but the audio feature for
    audio songs present at this web page is genuinely excellent.

  6. Thank you a bunch for sharing this with all people you actually recognise what you’re
    talking approximately! Bookmarked. Kindly additionally
    seek advice from my site =). We may have a hyperlink trade contract among us

网站地图