首页后端开发PHPphp中使用fsockopen实现异步请求(代码示例)

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

时间2024-02-02 00:46:03发布访客分类PHP浏览603
导读:收集整理的这篇文章主要介绍了php中使用fsockopen实现异步请求(代码示例),觉得挺不错的,现在分享给大家,也给大家做个参考。php执行一段程序,有可能几毫秒就执行完毕,也有可能耗时较长。例如,用户下单这个事件,如果调用了些第三方服务...
收集整理的这篇文章主要介绍了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.1\r\n";
        $out .= "Host: www.example.com\r\n";
        $out .= "Connection: Close\r\n\r\n";
         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.1\r\n";
        $out .= "Host:${
host}
    \r\n";
            $out .= "Content-type:application/x-www-form-urlencoded\r\n";
            $out .= "Content-length:".strlen($data)."\r\n";
            $out .= "Connection:close\r\n\r\n";
        $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.1\r\n";
        $out .= "Host:${
host}
    \r\n";
            $out .= "Connection:close\r\n\r\n";
            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实现异步请求(代码示例)的详细内容,更多请关注其它相关文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: php中使用fsockopen实现异步请求(代码示例)
本文地址: https://pptw.com/jishu/596138.html
Docker+LNMP+Jenkins+码云实现 PHP 代码自动化部署 PHP脚本导出MySQL数据字典(代码示例)

游客 回复需填写必要信息