百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> php中运用fsockopen实现异步要求(代码示例)
分享文章到:

php中运用fsockopen实现异步要求(代码示例)

发布时间:09/01 来源:未知 浏览: 关键词:

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实现异步恳求(代码示例)的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有151人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板