最近找轮询的资料,看到不错的文章就收藏进来javascript
没办法硬着头皮查找长轮询的资料吧~ 文字较多,耐心看看但愿对大家有帮助php
传送门
:Web 通讯 之 长链接、长轮询(long polling)html
看了不少,以为以上文章是最好的.里面说到轮询会出现的状况(文字功底很差只能拿来主意):前端
轮询的创建
创建轮询的过程很简单,浏览器发起请求后进入循环等待状态,此时因为服务器还未作出应答,因此HTTP也一直处于链接状态中。java
数据的推送
在循环过程当中,服务器程序对数据变更进行监控,如发现更新,将该信息输出给浏览器,随即断开链接,完成应答过程,实现“服务器推”。jquery
轮询的终止,轮询可能在如下3种状况时终止:ajax
轮询的重建
浏览器收到回复并进行相应处理后,应立刻从新发起请求,开始一个新的轮询周期。json
首先, 就是PHP后端的问题, 在轮询的时候后端会用while(true)的形式, 来hold住这个Ajax请求, 让他迟迟不能得到数据, 一旦获取数据前端Ajax立马就会作出飞通常的反应(网络好的时候确实飞呀飞~).后端
可是别太乐观, 一旦咱们的前端终止了请求, 那么服务端PHP就无限的循环下去, 他不会终止了! 伴随着ignore_user_abort(true)
和set_limit_time(0)
这个程序会很欢快的跑下去, 并且你会发现你的其余业务都会由于这样而中止!浏览器
你妈妈的吻~
查询了一些资料后, 是由于session处于被锁的状态.因此致使了其余页面也跟着不能正常了.解决方案: session_write_close()
, 页面总算正常了.
只不过呢? 程序仍是欢快的在后台放羊般的执行着, 并且你还不知道, 知道笔记本发热你才会觉察.
这个时候我就在想, 有没有一个PHP函数可让PHP知道前端已经断开了, 让死循环终止吧~
结果一Google~ 真有!!! 当当当当~~
connection_aborted() //就是他! 返回值: 未断开为false 断开为true
有了这个咱们就能够在客户端断开\关闭浏览器\Ajax超时执行的时候自动终止程序了.说了这么多, 感受仍是来看看代码吧.光说不练假把式~
这个代码只是一个测试例子, 测试效果是否被实现, 读者能够自行修改.
首先, 是前端HTML代码:
<html lang="en"> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="./jquery1.4.2.js"></script> <script type="text/javascript"> $(function () { var MsgBox = { MsgObj: $('#msg'), showMsg: function (msg) { MsgBox.MsgObj.html(msg); } } //轮询 var Comet = { Init: function () { $('#btn').unbind(); $('#btn').bind('click', Comet.Poll); }, //轮询 Poll: function () { //为了打日志写的东西,随机生成的 var id = parseInt(Math.random() * 1000); MsgBox.showMsg(''); $.ajax({ url: './test.php', //访问地址 type: 'post', //post方式提交 data: {id: id}, //传入ajax数据 dataType: 'json', //返回格式 timeout: 10000, //超时设置三十秒 success: Comet.Success, //成功时的返回 error: Comet.Failed //失败的时候 }); }, //成功获取数据时 Success: function (data) { if (data.status == 1) { MsgBox.showMsg(data.info); } }, //没有获取数据 Failed: function (XMLHttpRequest, textStatus, errorThrown) { //超时从新链接 if (textStatus == 'timeout') { Comet.Poll(); } else { Comet.Poll(); } } }; Comet.Init(); }); </script> </head> <body> <div id="msg"></div> <input type="button" value="开始" id="btn"> </body> </html>
这部分代码只是让前端在点击开始后,不断的Ajax提交访问请求, 添加了超时时间, 让Ajax能够在超时时候中断链接, 而后经过错误处理从新启动, 用递归来作循环吧(个人理解), 这个没有什么难度. 其实技术说穿了都那样白菜价.
而后是,Ajax请求中的test.php:
<?php //让脚本无限制执行下去 set_time_limit(0); ignore_user_abort(true); session_write_close(); $i=1; while(true){ //未断开链接就处理嘛 if(!connection_aborted()){ sleep(1); if($i >= 50) { echo json_encode(array('status'=>1, 'info'=>'lalalala')); break; } $i++; } } //断了链接,我就记录下,为了调试效果是否成功! 实际中看状况使用 if(!connection_aborted()){ echo json_encode(array('status'=>1, 'info'=>'中止了')); file_put_contents('stop.txt',"stop:".$_POST['id'].'-----'.date('Y-m-d H:i:s')."\n", FILE_APPEND); exit(); }
原连接:http://blog.csdn.net/xiaobaig0407/article/details/48676563
舒适提示:
HTML的代码里面jQuery库请自行添加, 我就不提供了.
在你点击了前端的"开始"后, 请注意咱们的Chrome中的时间线, 我设置了十秒超时, 因此你每隔10s就能够看到一个新的Ajax请求去访问后端PHP, 然后端有没有终止, 你只须要在Linux下的用tail -f stop.txt
这个日志文件就能够看到实时的日志变化.