PHP Ajax 長輪詢,簡稱 Comet(合稱基于 Comet 的 Web 應用程序)是一種新型的 web 開發技術,它的主要優勢在于可以實現實時向客戶端推送數據,減少了服務器與客戶端之間的通信次數,同時又可以保證數據的實時性。這種技術被應用的范圍非常廣泛,例如即時通訊、在線游戲等。
在 Ajax 中,客戶端可以通過 setInterval 函數定時向服務器發送請求,來獲取新數據。但這種方式效率不高,因為每次請求都要建立起連接,然后才能接受到響應。而 Comet 技術則允許服務器推送數據到客戶端。具體實現可以這樣:
function comet() { // 創建 XMLHttpRequest 對象 var xhr = new XMLHttpRequest(); // 發送請求,并告訴服務器自己是一次長輪詢 xhr.open("GET", "comet.php?type=poll", true); // 當對象狀態發生改變時 xhr.onreadystatechange = function() { // 4 = "loaded" if (xhr.readyState == 4) { // 200 = OK if (xhr.status == 200) { // 返回的數據就是服務器推送給我們的數據 var resp = xhr.responseText; // 處理返回的數據 handleResponse(resp); } } }; // 發送請求 xhr.send(null); }
在服務器端,先要檢測是否有新數據。如果沒有新數據,則服務器端會一直等待,直到新數據到來才返回。具體可以實現如下:
$lastime = isset($_GET['lastime']) ? $_GET['lastime'] : 0; while ( true ) { $starttime = time(); $sql = 'select * from msg where createtime >' . $lastime; $rs= mysql_query($sql, $dbconn); if(mysql_num_rows($rs) >0) { $data = array(); while($row = mysql_fetch_assoc($rs)) { $data[] = $row; } echo json_encode($data); exit; } else { sleep(1); } if ((time() - $starttime) >30) { exit; } }
在以上代碼中,服務器端通過檢查數據庫中是否有新消息,如果有,則將新消息發送給客戶端并結束程序。否則服務器端等待一秒鐘后再次循環。為了防止程序一直等待,程序增加了最多等待 30 秒的限制,如果超過這個時間,程序也會結束。
在 Ajax 長輪詢的使用過程中需要避免一些常見的問題,比如當服務器端發送消息時,客戶端還沒有接收到數據而直接關閉頁面,這時服務器端仍然會繼續發送數據,從而造成服務器資源浪費。解決這個問題可以通過預先設置一個計時器,在瀏覽器端關閉之前,先將計時器清除,再發送關閉請求。以下是一個典型的長輪詢計時器的實現:
var timer; function startRequest() { if (timer) clearTimeout(timer); timer = setTimeout(function () { comet(); }, 3000); } function handleResponse(response) { // 處理返回的數據 // ... // 處理完后再啟動計時器 startRequest(); } window.onbeforeunload = function() { if (timer) clearTimeout(timer); var xhr = new XMLHttpRequest(); xhr.open("GET", "comet.php?type=close", true); xhr.send(null); }
以上代碼使用 setInterval 函數定時發送請求,檢查是否有數據更新,同時需要注意客戶端與服務器端的并發性問題。如果存在一些資源競爭問題,則可能導致客戶端對未處理的數據進行多次回收請求,從而導致服務器負載過重,程序崩潰。
總之,使用 PHP Ajax 長輪詢可以有效地推送數據更新,減少服務器與客戶端之間的通信次數,提高用戶的使用體驗度。但是在使用過程中,需要注意一些并發性問題,避免對服務器造成過載,從而影響系統的穩定性。