socket与异步—异步(php版)
1.简单概念
异步:一种通讯方式,对设备需求简单。我们的PC机提供的标准通信接口都是异步的。
2. 为什么要用异步
由于php本身没有异步执行的机制,有时一些业务并不需要我们等到所有程序执行完再返回结果,这时用户体验就会比较不友好。例如发送邮件,用户操作完成后,并不需要一直等待直到邮件发送成功这个动作才结束。
3. 怎么实现异步
这里主要测试的是利用php的系统调用,开启新的进程来实现。
php 提供了fsockopen函数,此函数的功能为初始化一个套接字连接到指定主机,默认情况下将以阻塞模式开启套接字连接。当然你可以通过stream_set_blocking()将它转换到非阻塞模式。这是关键。所以,思路就是:开启一个非阻塞的套接字连接到本机,本机收到之后作一些耗时处理。
4. 案例:
异步调用的代码:posttest.php
<?php
$php_Path='127.0.0.1';
$fp = fsockopen($php_Path,80);
$key=uniqid();
$user=getClientIp();
if (!$fp) {
LMLog::error("fsockopen:err" );
} else {
$out = "GET /socket/album_write_friends_thread_record.php?key=$key&user=$user HTTP/1.1\r\n";
$out .= "Host: ".$php_Path."\r\n";
$out .= "Connection: Close\r\n\r\n";
stream_set_blocking($fp,true);
stream_set_timeout($fp,1);
fwrite($fp, $out);
usleep(1000);//这里,usleep(1000) 非常关键,它能保证这个请求能发出去。
fclose($fp);
}
echo "调用成功";
异步执行的代码:album_write_friends_thread_record.php,这里为了更好的看到效果,我用一张数据表来测试。
客户端调用服务器接口页面
<?php
sleep(3);// 睡眠3s
$key=isset($_GET['key']) ? $_GET['key'] : "";
$ip=isset($_GET['user']) ? $_GET['user'] : "";
$con = mysql_connect("localhost","数据库用户","数据库密码");
$select_db = mysql_select_db('test');
if (!$select_db) {
die("could not connect to the db:\n" . mysql_error());
}
$time=time();
//插入数据库
$sql = "INSERT INTO tb_time (time,k_ey,ip) VALUES ($time,'$key','$ip')";
$res = mysql_query($sql);
if (!$res) {
die("could get the res:\n" . mysql_error());
}else{
echo "执行成功";
}
mysql_close($con);//关闭数据库连接
?>
数据表结构:
CREATE TABLE `tb_time` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '时间',
`k_ey` varchar(32) NOT NULL DEFAULT '' COMMENT '字符串',
`ip` varchar(15) NOT NULL DEFAULT '' COMMENT 'IP',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
此时数据表为空
此时执行下异步调用的代码,不需要等待sellp的完成
等待3s后查询数据库会发现异步执行已经成功
实际上,我们服务器在执行fsockopen 那段程序时,就不会再等3s之后才能返回给客户端,而是发出这个请求之后,即返回客户端,销毁进程,而把剩余的工作交由其他进程慢慢做去,这就实现了php的异步。
具体的实现就看业务的需要,这里只分享下简单的测试应用。
(注:本文转载至:https://www.cnblogs.com/qingfj/p/9663651.html ,谢谢博主的总结)