zoukankan      html  css  js  c++  java
  • php 使用fsockopen 发送http请求

    https://www.cnblogs.com/wt645631686/p/11360148.html

    需求背景

    在公司开发这么一个需求,每天三次定时催付待客服催付状态的订单,设定每天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("
    ", $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("
    ", $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
    ";
            $request.="Host: ".$URL_Info["host"]."
    ";
            $request.="Referer: $referrer
    ";
            $request.="Content-type: application/x-www-form-urlencoded
    ";
            $request.="Content-length: ".strlen($data_string)."
    ";
            $request.="Connection: close
    ";
            $request.="
    ";
            $request.=$data_string."
    ";
    
            $fp = fsockopen($URL_Info["host"],$URL_Info["port"],$errno, $errstr);
            if (!$fp) {
                EdjLog::info('socket_open error:'.json_encode($data). "Error: $errstr ($errno)");
            }
            fputs($fp, $request);
    //        $result = '';
    //        while(!feof($fp)) {
    //
    //            $response = fgets($fp, 512);
    //            if (!is_numeric(trim($response))) {
    //                continue;
    //            }
    //            $result.= $response;
    //        }
            fclose($fp);
    //        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
    "; 
      $post_header .= "Content-Type: application/x-www-form-urlencoded
    "; 
      $post_header .= "User-Agent: MSIE
    "; 
      $post_header .= "Host: ".$srv_ip."
    "; 
      $post_header .= "Content-Length: ".$content_length."
    "; 
      $post_header .= "Connection: close
    
    "; 
      $post_header .= $post_str."
    
    "; 
      fwrite($fp,$post_header); 
     
      $inheader = 1; 
      while(!feof($fp)){//测试文件指针是否到了文件结束的位置 
       $line = fgets($fp,1024); 
       //去掉请求包的头信息 
       if ($inheader && ($line == "
    " || $line == "
    ")) { 
             $inheader = 0; 
        } 
        if ($inheader == 0) { 
          echo $line; 
        } 
      } 
      fclose($fp); 
      unset ($line); 
    ?>
  • 相关阅读:
    加入创业公司有什么利弊
    Find Minimum in Rotated Sorted Array II
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Find Minimum in Rotated Sorted Array
    Remove Duplicates from Sorted Array
    Spiral Matrix
    Spiral Matrix II
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/yszr/p/11362605.html
Copyright © 2011-2022 走看看