fsockopen 异步处理
浏览:9844次 出处信息
前面参与一项目,逻辑处理比较多,所以采用异步处理。
因为之前采用异步处理时 Web 服务器是 Apache,而这次测试时也是,到把代码更新到服务器上时,执行死活不成功。折腾一番之后,才记起服务器上的 Web 服务器是 Nginx。试着从这个角度查找原因,找到如下这篇文章:
FROM: 有关fsockopen相关随笔
测试环境,从本机(Windows)访问内外一台 Linux 服务器(此服务器装的是 Nginx)。
index.php 代码:
1 使用HTTP 1.1 协议请求
function asyn_sendmail() {
$ip = '192.168.1.45';
$url = '/index.php';
$fp = fsockopen($ip, 80, $errno, $errstr, 5);
if (!$fp) {
echo "$errstr ($errno)
\\n";
}
$end = "\\r\\n";
$input = "GET $url HTTP/1.1$end";
//如果不加下面这一句,会返回一个 HTTP400 错误
//$input.="Host: $ip$end";
//如果不加下面这一句,请求会阻塞很久
//$input.="Connection: Close$end";
$input.="$end";
fputs($fp, $input);
$html = '';
while (!feof($fp)) {
$html.=fgets($fp);
}
fclose($fp);
writelog($html);
echo $html;
}
function writelog($message) {
$path = 'log.txt';
$handler = fopen($path, 'w+b');
if ($handler) {
$success = fwrite($handler, $message);
fclose($handler);
}
}
asyn_sendmail();
如果注释了 $input.="Host: $ip$end"; 这一句,则会得到一个 404 错误,log.txt 内容如下:
HTTP/1.1 400 Bad Request Server: nginx/0.8.46 Date: Fri, 30 Dec 2011 02:11:45 GMT Content-Type: text/html Content-Length: 173 Connection: close400 Bad Request
nginx/0.8.46
说明:使用 HTTP 1.1 连接,则必须加上 Host请 求表头。
如果加上了没有注释 $input.="Host: $ip$end"; 这一句 ,则请求成功,log.txt 内容如下:
HTTP/1.1 200 OK Server: nginx/0.8.46 Date: Fri, 30 Dec 2011 02:20:49 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding X-Powered-By: PHP/5.3.8 1 0 0
返回成功,但是不明白为什么服务器返回内容多了2个 0 (后来网上查询资料发现,这是因为服务器使用了 chunked 输出所致,用 Wireshark 抓包可清晰看到其细节)。如果不加 $input.="Connection: Close$end"; 这一句 ,则 HTTP 请求会阻塞很久(在这一句 fgets($fp) 阻塞)。
2 不指定 HTTP 版本
\\n";
}
$end = "\\r\\n";
$input = "GET $url$end";
$input.="$end";
fputs($fp, $input);
$html = '';
while (!feof($fp)) {
$html.=fgets($fp);
}
fclose($fp);
writelog($html);
echo $html;
}
function writelog($message) {
$path = 'log.txt';
$handler = fopen($path, 'w+b');
if ($handler) {
$success = fwrite($handler, $message);
fclose($handler);
}
}
asyn_sendmail();
?>
请求立刻返回,没有阻塞,返回内容如下:
1
注意:返回内容中没有http标头,且没有被阻塞。
参考上面,代码中,发送到头部信息中正是少了第一段中提到的 $input.="Connection: Close$end";,添加上,问题解决。
总结:
fsockopen 上采用 POST 方法的代码:
$domain = "localhost";
$url = '/tool/async-test.php';
$param = "a=1&b=2&c=3&d=4";
$header = "POST $url HTTP/1.1\\r\\n";
$header .= "Host: $domain\\r\\n";
$header .= "Content-Type:application/x-www-form-urlencoded\\r\\n";
$header .= "Content-Length:" . strlen($param) . "\\r\\n\\r\\n";
$header .= "Connection: close\\r\\n";
$fp = @fsockopen($domain, 80, $errno, $errstr, 30);
fputs($fp, $header.$param);
$html = '';
while (!feof($fp)) {
$html.=fgets($fp);
}
echo $html;
fclose($fp);
建议继续学习:
- 关于IO的同步,异步,阻塞,非阻塞 (阅读:15779)
- 配合jquery实现异步加载页面元素 (阅读:5937)
- 使用django+celery+RabbitMQ实现异步执行 (阅读:5708)
- 多核与异步并行 (阅读:4631)
- 异步编程与响应式框架 (阅读:4520)
- Google Analytics 异步代码详解 (阅读:3916)
- redis源代码分析 - event library (阅读:3777)
- 异步完成后新开窗口 (阅读:3551)
- php的异步http请求类 (阅读:3440)
- Script 元素的异步加载属性 (阅读:3059)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:PHP安全之慎用preg_replace的/e修饰符
后一篇:用php根据ip获取地区的方法 >>
文章信息
- 作者:Summer 来源: 生活在別處
- 标签: fsockopen 异步
- 发布时间:2012-05-17 23:28:23
建议继续学习
近3天十大热文
-
[917] WordPress插件开发 -- 在插件使用 -
[135] 解决 nginx 反向代理网页首尾出现神秘字 -
[54] 整理了一份招PHP高级工程师的面试题 -
[53] 如何保证一个程序在单台服务器上只有唯一实例( -
[52] Innodb分表太多或者表分区太多,会导致内 -
[52] 海量小文件存储 -
[51] 全站换域名时利用nginx和javascri -
[51] 用 Jquery 模拟 select -
[50] CloudSMS:免费匿名的云短信 -
[48] jQuery性能优化指南
