2014-04-16 54 views
0

我正在嘗試製作傳入消息的通知系統。對於examlpe用戶停留在頁面上,他在一個塊中接收到他有2條未讀消息。長查詢服務器循環

我的客戶端代碼:

(function getmess(){ 
var id = '<?=$MY_ID;?>'; 
    $.ajax({ 
     url:"notif.php", 
     data:{"id":id,}, 
     type:"GET", 
     success: function(result){ 
     $("#count").html(result); 
     }, dataType: "json", 
     complete: getmess, 
     timeout: 10000}); 
})(); 

我的服務器代碼:

<?php 
    $mysqli = new mysqli('localhost', 'root', '', 'lc'); 
    if (mysqli_connect_errno()) { 
     printf("error: %s\n", mysqli_connect_error()); 
     exit; 
    } 

$MY_ID = $_POST['id']; 

while (true) { 
$result = $mysqli->query("SELECT COUNT(*) FROM messages WHERE user_get='$MY_ID' AND status='0' "); 
if (mysqli_num_rows($result)) { 
while ($row = mysqli_fetch_array($result)) { 
echo $row[0].""; 
} 
exit; 
} 
sleep(5); 
} 

一切正常,但我的問題是,AJAX請求發送每隔1秒和這些請求的lengh爲1其次,他們超載服務器。

我想等待服務器響應至少10秒,如果成功響應立即發送新的請求,以及如果服務器在10秒內沒有響應,即在那裏的數據庫是沒有變化的,然後發送一個新的查詢長度爲10秒。

我認爲這是錯誤的東西與服務器(可切斷迴路),但我不知道如何改進這一點。

+1

我建議使用websockets來代替。 – Oriol

+0

您的客戶端代碼有問題,而不是服務器。你必須用'setTimeout'包裝'getmess'調用。 – hindmost

回答

1

我很抱歉地說,這是不會,因爲每個用戶的工作,你的服務器有一個開放的線程。這真的很重。

這將是最好只輪詢服務器即。每分鐘一次,然後讓服務器處理該請求一次,而不是保持打開狀態。

這是可能的,雖然,只是沒有用PHP。例如,檢出http://cometd.org/

0

雖然有其他可供選擇,如果你用投票去,有你需要修復的幾件事情:

  • 不要使用間隔爲你投票,而不是使用您設置超時在ajax請求的成功函數中。這樣你就不必擔心請求重疊。
  • 由於javascript正在進行輪詢,請不要在您的php中使用循環來輪詢新的數據庫條目。只需檢查一次並將結果返回給瀏覽器。
  • 注意,在數據庫中沒有任何變化是正常的,成功的數據庫 查詢,以便你可以發送回一個空的結果。我會返回json 帶有數據庫條目列表或一個空列表,如果沒有找到,並在javascript中處理這些結果。

簡而言之,只需在php中快速檢查數據庫,然後在javascript中處理其餘部分。

+0

但是我怎麼能強制我的腳本等待10秒或20秒以響應來自服務器而不是1秒? – user3140144

+0

@ user3140144你的腳本不用等那麼久,響應應該是中等的。等待應該用javascript來完成,例如'setTimeout()'。 – jeroen

+0

是的,但長輪詢意味着我們等待例如20秒鐘的服務器響應(在我的情況下:如果數據庫已更改),如果有事情改變了服務器的響應,但如果沒有任何變化,我們發送新的請求並再次等待20秒。 – user3140144