PHP Ajax轮询

最近找轮询的资料,看到不错的文章就收藏进来javascript

看重点! 这里只讲轮询!

没办法硬着头皮查找长轮询的资料吧~ 文字较多,耐心看看但愿对大家有帮助php

传送门:Web 通讯 之 长链接、长轮询(long polling)html

看了不少,以为以上文章是最好的.里面说到轮询会出现的状况(文字功底很差只能拿来主意):前端

  1. 轮询的创建 
    创建轮询的过程很简单,浏览器发起请求后进入循环等待状态,此时因为服务器还未作出应答,因此HTTP也一直处于链接状态中。java

  2. 数据的推送 
    在循环过程当中,服务器程序对数据变更进行监控,如发现更新,将该信息输出给浏览器,随即断开链接,完成应答过程,实现“服务器推”。jquery

  3. 轮询的终止,轮询可能在如下3种状况时终止:ajax

    • 有新数据推送 
      当循环过程当中服务器向浏览器推送信息后,应该主动结束程序运行从而让链接断开,这样浏览器才能及时收到数据。
    • 没有新数据推送 
      循环不能一直持续下去,应该设定一个最长时限,避免WEB服务器超时(Timeout),若一直没有新信息,服务器应主动向浏览器发送本次轮询无新信息的正常响应,并断开链接,这也被称为“心跳”信息。
    • 网络故障或异常 
      因为网络故障等因素形成的请求超时或出错也可能致使轮询的意外中断,此时浏览器将收到错误信息。
  4. 轮询的重建 
    浏览器收到回复并进行相应处理后,应立刻从新发起请求,开始一个新的轮询周期。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这个日志文件就能够看到实时的日志变化.

相关文章
相关标签/搜索