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這個日誌文件就能夠看到實時的日誌變化.

相關文章
相關標籤/搜索