php 使用fsockopen 发送http请求

php 使用fsockopen 发送http请求,第1张

概述需求背景在公司开发这么一个需求,每天三次定时催付待客服催付状态的订单,设定每天15、16、17点三次执行job任务来给一批订单打电话催付,需要三个时间点都把待客服催付的订单拨打一遍电话,根据数据组统计,大概每天需要催付的订单数量在6000左右,对接第三方电话呼叫业务,拿到订单信息来呼

需求背景

在公司开发这么一个需求,每天三次定时催付待客服催付状态的订单,设定每天15、16、17点三次执行job任务来给一批订单打电话催付,需要三个时间点都把待客服催付的订单拨打一遍电话,根据数据组统计,大概每天需要催付的订单数量在6000左右,对接第三方电话呼叫业务,拿到订单信息来呼叫。

测试状态

拿500个订单手动执行第一波测试,发现500个订单催付完毕需要30多分钟,那么6000个订单按照需求催付时间点是完全不够的,半小时500个,一小时最多1000个。

初步排查,是由于使用PHP  curl请求导致每一次遍历的请求时间慢,由于curl请求最短的time时间耗时是1秒,那么一小时3600秒也是不够呼完这6000单。

解决方案

一、在遍历循环的时候把每次请求的量丢入消费系统(队列),然后根据开启多个消费者来消费这些(上线迫在眉睫,来不及)

二、有没有类似curl更快的方案,发现了fsockopen,按照使用方法配置完500个订单,遍历完成只需要18秒。

需求代码

  /**     * 通过订单信息组装呼叫信息     * @param array $order     * @return array     */    private function getCallinfoByOrder ($order = [])    {        $order_ext  = OrderExt::model()->getPrimary($order['order_ID']);        $point      = (isset($order_ext['app_ver'])&&version_compare($order_ext['app_ver'],Tools::PRICE_COMPARE_VERSION,">="));        $pay_detail     = Json_decode($order['pay_detail'], true);        $call_text      = OrderPayRemainService::organizeHeliText($order['create_time'], $pay_detail['cash'], $point);        return ['phone' => $order['phone'], 'call_text' => $call_text];    }    //开始呼叫    private function toCall ($call_info)    {        $params = $this->formatGetParams($call_info);        EdjLog::info(__METHOD__ .'he li to call info' . Json_encode($call_info));       $this->doCurlGetRequest(self::CALL_API_URL, $params, $call_info);    }    //拨号请求    private function doCurlGetRequest($url, $data = [],  $call_info = []){        if($url == "" || empty($data)){            return false;        }        $response = $this->fsockopen_request($url,$data);//        $response_arr = explode("\r\n", $response);////        if (in_array(self::TOOKEN_INVALID,$response_arr)) {//            EdjLog::info(__METHOD__ .'he li accesstoken expire' . Json_encode($call_info));//            $this->redis->del(self::ACCESS_TONEN_CACHE_KEY);//            $this->toCall($call_info);//        }   $response_arr = explode("\r\n", $response);        return true;    }
 private function fsockopen_request($URL,$data, $referrer="") {
EdjLog::info(__METHOD__ .'he li request url:' . $URL.'-data:'.Json_encode($data));
$URL_Info = parse_url($URL);
foreach($data as $key=>$value)
$values[] = "$key=" . urlencode($value);
$data_string = implode("&",$values);
if(!isset($URL_Info["port"]))
$URL_Info["port"] = 80;
$request = '';
$request.="POST ".$URL_Info["path"]." http/1.1\n";
$request.="Host: ".$URL_Info["host"]."\n";
$request.="Referer: $referrer\n";
$request.="Content-type: application/x-www-form-urlencoded\n";
$request.="Content-length: ".strlen($data_string)."\n";
$request.="Connection: close\n";
$request.="\n";
$request.=$data_string."\n";

$fp = fsockopen($URL_Info["host"],$URL_Info["port"],$errno, $errstr);
if (!$fp) {
EdjLog::info('socket_open error:'.Json_encode($data). "Error: $errstr ($errno)");
} else {
stream_set_blocking($fp, true);//开启了非阻塞模式
fputs($fp, $request);
fclose($fp);
usleep(400000); //等待500ms
EdjLog::info('socket_open success:'.Json_encode($data));
}
// $result = '';
// while(!feof($fp)) {
//
// $response = fgets($fp, 512);
// if (!is_numeric(trim($response))) {
// continue;
// }
// $result.= $response;
// }

// return $result;
}

完整说明

<?PHP   $srv_ip = '192.168.1.5';//你的目标服务地址.   $srv_port = 80;//端口   $url = 'http://localhost/fsock.PHP'; //接收你post的URL具体地址    $fp = '';   $errno = 0;//错误处理   $errstr = '';//错误处理   $timeout = 10;//多久没有连上就中断   $post_str = "username=demo&password=hahaha";//要提交的内容.   //打开网络的 Socket 链接。   $fp = fsockopen($srv_ip,$srv_port,$errno,$errstr,$timeout);   if (!$fp){    echo('fp fail');   }   $content_length = strlen($post_str);   $post_header = "POST $url http/1.1\r\n";   $post_header .= "Content-Type: application/x-www-form-urlencoded\r\n";   $post_header .= "User-Agent: MSIE\r\n";   $post_header .= "Host: ".$srv_ip."\r\n";   $post_header .= "Content-Length: ".$content_length."\r\n";   $post_header .= "Connection: close\r\n\r\n";   $post_header .= $post_str."\r\n\r\n";   fwrite($fp,$post_header);    $inheader = 1;   while(!feof($fp)){//测试文件指针是否到了文件结束的位置    $line = fgets($fp,1024);    //去掉请求包的头信息    if ($inheader && ($line == "\n" || $line == "\r\n")) {          $inheader = 0;     }     if ($inheader == 0) {       echo $line;     }   }   fclose($fp);   unset ($line); ?> 

其它博文

https://blog.csdn.net/navioo/article/details/82771663

总结

以上是内存溢出为你收集整理的php 使用fsockopen 发送http请求全部内容,希望文章能够帮你解决php 使用fsockopen 发送http请求所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1001649.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存