【学无止境】ajax长循环,反向ajax初体会,不用ws实现即时聊天
反向ajax
ajax長(zhǎng)循環(huán),又叫comet機(jī)制,但是我最喜歡的還是叫他反向ajax
反向ajax,顧名思義,就是不是客戶端來請(qǐng)求服務(wù)器端,而是服務(wù)器端請(qǐng)求客戶端,這樣做的好處是節(jié)省了大量以前輪詢?cè)斐傻牟樵兝速M(fèi),從而減輕數(shù)據(jù)庫(kù)壓力和服務(wù)器壓力
那么如何實(shí)現(xiàn)反向ajax呢:
主體
1.在客戶端寫一個(gè)ajax,這個(gè)ajax里設(shè)置一個(gè)過期的時(shí)間 timeout,這個(gè)過期的時(shí)間timeout是用來暫時(shí)延長(zhǎng)ajax的請(qǐng)求時(shí)間的,當(dāng)這個(gè)ajax觸發(fā)的時(shí)候給后臺(tái)傳遞一個(gè)等于timeout的值。
$.ajax({type: 'POST',dataType: 'json',url: "do.php",timeout: '20000',//請(qǐng)求超時(shí)時(shí)間data: {'time':'2000000','user':user},// 每次請(qǐng)求等待時(shí)間success: function(data){//邏輯代碼 })2.在后臺(tái)的php文件中,我們接受這個(gè)timeout,把這個(gè)timeout設(shè)置為php的擱置時(shí)間,這樣就算掛起了php處理的這個(gè)進(jìn)程了,這樣做是為了和前面ajax的過期時(shí)間保持一致,從而一致保持ajax請(qǐng)求這個(gè)狀態(tài),也就是說在這timeout時(shí)間內(nèi)
ajax的請(qǐng)求和php處理程序進(jìn)程被掛起了
$time = $_POST['time']; $user = $_POST['user']; if(empty($time)) exit(); set_time_limit(0);// 無限請(qǐng)求超時(shí)時(shí)間 usleep($time);// 等待時(shí)間重點(diǎn)
3.重點(diǎn)的一步:在一個(gè)while循環(huán)中處理自己的業(yè)務(wù)邏輯,然后向前端發(fā)送信息,隨后退出當(dāng)前的線程,這樣做的意義是沾少量的內(nèi)存和查最少的數(shù)據(jù)庫(kù)
while(true){if(你自己的判斷向客服端發(fā)送信息的條件)//send()發(fā)送信息后退出線程exit();}else{//無數(shù)據(jù)發(fā)送直接退出線程exit(); }4.前端重要的一步:當(dāng)你從后端拿出你要的東西時(shí)候,將結(jié)束上一個(gè)長(zhǎng)循環(huán),然后掛起下一個(gè)長(zhǎng)循環(huán)ajax,就算你沒有拿到數(shù)據(jù)過了超時(shí)時(shí)間的話也要結(jié)束當(dāng)前ajax,進(jìn)行下一個(gè)ajax。如果沒有數(shù)據(jù)這個(gè)ajax會(huì)持續(xù)20s,這可比主動(dòng)每秒訪問服務(wù)器好多了,這是服務(wù)器主動(dòng)推的,不是客戶端每秒輪詢的。
success: function(data){//邏輯代碼 } // 未從服務(wù)器中獲的數(shù)據(jù),繼續(xù)擱置 if(data.success == '0'){ajax_for_while() }// ajax超時(shí),進(jìn)入下一個(gè)push擱置機(jī)制 error:function(XMLHttpRequest,textStatus,errorThrown){if(textStatus == "timeout"){ajax_for_while()} }core
客戶端發(fā)起一個(gè)ajax請(qǐng)求,服務(wù)端將請(qǐng)求擱置(pending)或者說掛起,直到到了超時(shí)時(shí)間(timeout)或需要推送時(shí)返回;客戶端則等待ajax返回后處理數(shù)據(jù),再發(fā)起下一個(gè)ajax請(qǐng)求。
這樣的掛起就不是服務(wù)器每秒請(qǐng)求ajax的數(shù)據(jù)庫(kù)了,這個(gè)timeout時(shí)間是可以更改的,多少都行。現(xiàn)在是20s,在20s內(nèi)ajax不會(huì)不斷請(qǐng)求數(shù)據(jù)庫(kù),或服務(wù)器,問他們有沒有信息,而是一旦服務(wù)器有信息就會(huì)主動(dòng)推送給客戶端,而不用客戶端每秒都詢問了。
完整的代碼
前端的
function ajax_for_while() {//AJAX長(zhǎng)輪詢$.ajax({type: 'POST',dataType: 'json',url: "do.php",timeout: '20000',//請(qǐng)求超時(shí)時(shí)間data: {'time':'2000000','user':user},// 每次請(qǐng)求等待時(shí)間success: function(data){if(data.success == '1')ajax_for_while()}// 未從服務(wù)器中獲的數(shù)據(jù)if(data.success == '0'){ajax_for_while()}},// ajax超時(shí),進(jìn)入下一個(gè)push擱置機(jī)制error:function(XMLHttpRequest,textStatus,errorThrown){if(textStatus == "timeout"){ajax_for_while()}}}); }后臺(tái)的
$time = $_POST['time']; $user = $_POST['user']; if(empty($time)) exit(); set_time_limit(0);// 無限請(qǐng)求超時(shí)時(shí)間 usleep($time);// 等待時(shí)間 while(true){//在數(shù)據(jù)庫(kù)中查找相應(yīng)的最后條未讀數(shù)據(jù)出來if(empty($user_record_array)){$arr = array('success'=>'0','error'=>'無新數(shù)據(jù)');echo json_encode($arr);exit();}else{if($user_record_array['state'] == 0){$arr = array('success'=>'0','error'=>'有數(shù)據(jù)'); echo json_encode($arr); exit();}else{$arr = array('success'=>'0','error'=>'無新數(shù)據(jù)');echo json_encode($arr);exit();}}}參考資料
http://www.cnblogs.com/MGer-PHP/p/3701573.html
http://blog.csdn.net/black_ox/article/details/12981195
總結(jié)
以上是生活随笔為你收集整理的【学无止境】ajax长循环,反向ajax初体会,不用ws实现即时聊天的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【laravel】我和laravel的旅
- 下一篇: 【laravel】用laravel在游览