Ajax/jsonp/iframe+PHP实现“服务器推”技术:comet http长轮询实例
用长轮询方式实现服务器推技术,其技术要点以下两点:
- 1.客户端发出请求后服务器如果未查询到数据,不要立刻返回,而是用一个死循环一直循环查询需要获取的数据,每隔一秒查一次(sleep),直到查到有数据后返回,或者一直未查到数据但已超时也要返回,以php为例(纯手写,未经测试,但原理是酱紫的):
<?php
//定义计时器$i
$timer = 0;
//定义超时时间,这个时间根据nginx服务器配置的超时时间酌情设置即可,我认为比超时时间少一两秒最好。
$timeout = 25;
while(1) {
//去数据库或者redis/memcache等查询所需数据
$data = getData();
if(!empty($data)) {
echo json_encode([
'code' = >0,
'msg' => '成功,返回数据',
'data' => $data,
]);
exit();
}
if($timer>=$timeout) {
echo json_encode([
'code' = > -1,
'msg' => '失败,超时返回',
'data' => $data,
]);
exit();
}
//每隔一秒查一次
sleep(1);
//每执行一次,计时器加1,这里理论上是查了几次就用了几秒,但实际上因为查询也需要时间
//所以这个$timer的数字比实际时间小一点点,比如$timer=25时,实际可能花了27秒,
//而一个http连接是有超时时间的(在nginx中设置),如果我们必须在http连接超时前返回,否则就会因为nginx超时直接断开链接而无法重新发起请求了
$timer++;
}
- 2、服务器返回后不管是否有数据,必须再次发起请求,有数据可以处理数据在页面显示后再发起请求,没数据可直接发起请求,当然也可以根据实际需求用setTimeout延迟一秒两秒再发起请求(比较服务器端如果一直有数据,客户端则不能在请求返回后马上发起请求,因为这样会造成请求太频繁,可以500ms或1s后再发起),总之,请求不能断,服务器再次重复前面的步骤,如此往复。
长轮询的优点:
- 1)响应及时,有数据时,最多延迟1秒即可返回
- 2)极大减少了空请求,进而减少了由于http三次握手导致的服务器资源消耗
长轮询的缺点:
– 1)当服务器一直查询到有数据时,长轮询退化为简单的机械轮询,一样会导致请求频繁,但对于非大型应用,这个可以不考虑。
– 2)有人说服务器用死循环每隔一秒查一次会占用服务器资源,理论上确实是这样的,但我不知道这个占用的资源,跟频繁请求比起来哪个消耗资源更多,微信登录用的就是这种长轮询方式,很多人也推荐使用长轮询,所以到底直接轮询好还是长轮询好还有待讨论。
。。。未完待续
觉得文章对你有用的话鼓励一下我吧