欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          php中使用fsockopen實(shí)現(xiàn)異步請(qǐng)求(代碼示例)

          php中使用fsockopen實(shí)現(xiàn)異步請(qǐng)求(代碼示例)

          php執(zhí)行一段程序,有可能幾毫秒就執(zhí)行完畢,也有可能耗時(shí)較長。

          例如,用戶下單這個(gè)事件,如果調(diào)用了些第三方服務(wù)進(jìn)行發(fā)郵件、短信、推送等通知,可能導(dǎo)致前端一直在等待。

          而有的時(shí)候,我們并不關(guān)心這些耗時(shí)腳本的返回結(jié)果,只要執(zhí)行就行了。這時(shí)候就需要采用異步的方式執(zhí)行。

          眾所周知,PHP沒有直接支持多線程這種東西。我們可以采用折衷的方式實(shí)現(xiàn)。這里主要說的就是fsockopen。

          通過fsockopen發(fā)送請(qǐng)求并忽略返回結(jié)果,程序可以馬上返回。

          示例代碼:

          $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);     /*忽略執(zhí)行結(jié)果     while (!feof($fp)) {         echo fgets($fp, 128);     }*/     fclose($fp); }

          需要注意的是我們需要手動(dòng)拼出header頭信息。通過打開注釋部分,可以查看請(qǐng)求返回結(jié)果,但這時(shí)候又變成同步的了,因?yàn)槌绦驎?huì)等待返回結(jié)果才結(jié)束。

          實(shí)際測試的時(shí)候發(fā)現(xiàn),不忽略執(zhí)行結(jié)果,調(diào)試的時(shí)候每次都會(huì)成功發(fā)送sock請(qǐng)求;但忽略執(zhí)行結(jié)果,經(jīng)常看到?jīng)]有成功發(fā)送sock請(qǐng)求。查看nginx日志,發(fā)現(xiàn)很多狀態(tài)碼為499的請(qǐng)求。

          后來找到了原因:

          fwrite之后馬上執(zhí)行fclose,nginx會(huì)直接返回499,不會(huì)把請(qǐng)求轉(zhuǎn)發(fā)給php處理。

          客戶端主動(dòng)端口請(qǐng)求連接時(shí),NGINX 不會(huì)將該請(qǐng)求代理給上游服務(wù)(FastCGI PHP 進(jìn)程),這個(gè)時(shí)候 access log 中會(huì)以 499 記錄這個(gè)請(qǐng)求。

          解決方案:

          1)nginx.conf增加配置

          # 忽略客戶端中斷 fastcgi_ignore_client_abort on;

          2)fwrite之后使用usleep函數(shù)休眠20毫秒:

          usleep(20000);

          后來測試就沒有發(fā)現(xiàn)失敗的情況了。

          附上完整代碼:

          <?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);         //忽略執(zhí)行結(jié)果;否則等待返回結(jié)果 //        if(APP_DEBUG === true){         if(false){             $ret = '';             while (!feof($fp)) {                 $ret .= fgets($fp, 128);             }         }         usleep(20000); //fwrite之后馬上執(zhí)行fclose,nginx會(huì)直接返回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);         //忽略執(zhí)行結(jié)果;否則等待返回結(jié)果 //        if(APP_DEBUG === true){         if(false){             $ret = '';             while (!feof($fp)) {                 $ret .= fgets($fp, 128);             }         }         usleep(20000); //fwrite之后馬上執(zhí)行fclose,nginx會(huì)直接返回499         fclose($fp);     }     } ?>

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)