PHP异步请求之fsockopen()方法详解

2021-01-29 15:16:50  [ php ]      留言:0      阅读:6

来源:


随笔 - 115  文章 - 22  评论 - 65  阅读 - 700714

PHP异步请求之fsockopen()方法详解

正常情况下,PHP执行的都是同步请求,代码自上而下依次执行,但有些场景如发送邮件、执行耗时任务等操作时就不适用于同步请求,只能使用异步处理请求。

场景要求:

客户端调用服务器a.php接口,需要执行一个长达10s-20s不等的耗资源操作,假如客户端响应请求时间为5秒(请求响应超时时间),5s以上无回复即断开连接。

解决设想:

客户端调用a.php之后,a.php执行异步多线程操作调用b.php,a.php调用成功后即刻反馈给客户端回执,b.php自动执行耗资源操作。

方案:

利用fsockopen()方法解决PHP异步请求

1.封装异步请求函数asyncRequest(),代码如下:

复制代码
/**
     * php异步请求
     * @param $host string 主机地址
     * @param $path string 路径
     * @param $param array 请求参数
     * @return string */ private static function asyncRequest($host, $path, $param = array()){ $query = isset($param) ? http_build_query($param) : '';
        Bd_Log::debug($query); $port = 80; $errno = 0; $errstr = ''; $timeout = 30; //连接超时时间(S) $fp = @fsockopen($host, $port, $errno, $errstr, $timeout); //$fp = stream_socket_client("tcp://".$host.":".$port, $errno, $errstr, $timeout); if (!$fp) {

            Bd_Log::debug('连接失败'); return '连接失败';
        } if ($errno || !$fp) {

            Bd_Log::debug($errstr); return $errstr;
        } stream_set_blocking($fp,0); //非阻塞 stream_set_timeout($fp, 1);//响应超时时间(S) $out = "POST " . $path . " HTTP/1.1\r\n"; $out .= "host:" . $host . "\r\n"; $out .= "content-length:" . strlen($query) . "\r\n"; $out .= "content-type:application/x-www-form-urlencoded\r\n"; $out .= "connection:close\r\n\r\n"; $out .= $query; $result = @fputs($fp, $out);

        @fclose($fp); return $result;

    }
复制代码

实例:

正常接口a.php,如下

复制代码
    /**
     * 正常接口a.php
     * @param $host string 主机地址
     * @param $path string 路径
     * @param $param array 请求参数 */   public function a(){ $param = array( 'XXX' => $XXX, ); $asyncData = $this->asyncRequest( $host, $path ,$param); echo'a.php success'   }
复制代码

耗时接口b.php,如下

复制代码
    /**
     * 耗时接口b.php,依次输出三种结果 */ public function b(){
    
      set_time_limit(0); ignore_user_abort(true);//设置与客户机断开是否会终止执行 fastcgi_finish_request();//提高请求的处理速度    sleep(30); echo "耗时30秒"; sleep(20); echo "耗时20秒"; sleep(10); echo "耗时10秒";
    }
复制代码

 

上述实例即为简单的测试接口部分代码,根据自己需求做修改即可;

 

作者:申文哲

如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

如果希望更容易地发现我的新博客,记得在左下角点个“关注我”哦。(如有错误之处,还请指正!)

posted @ 2019-01-03 12:02  申文哲  阅读(5366)  评论(3编辑  收藏

评论列表
  
#1楼 2019-01-30 11:06 刀狂剑痴叶小钗
马克一下,很哟用
  
#2楼 2019-09-04 16:05 one852
能给我联系方式不 要请教个问题

我PHP发起一个异步请求
被请求的PHP文件里加了sleep(),但是异步请求的时候直接忽略了sleep() 直接执行了下面的代码
  
#3楼 [楼主] 2019-09-05 14:13 申文哲
@ one852
异步请求的代码中加入了sleep(30),没生效?可以多打印几处日志排查问题

来源:


留言:


    更换校验码     

无觅相关文章插件,快速提升流量
分享到:
友荐云推荐 Process: 0.0398s ( Load:0.0003s Init:0.0009s Exec:0.0243s Template:0.0143s ) | DB :14 queries 1 writes | UseMem:3,047 kb