2013-03-23 54 views
3

我正在開發現場拍賣現場,有實時招標系統。我在使用長輪詢當用戶對物品進行投標時。我選擇了長輪詢因爲的WebSockets都還不是很支持,的NodeJS是複雜,我現在實現。所以我堅持使用這個simle ajax長輪詢,這對大約五個出價很有用。LONG POLLING(在php中)5個請求後開始掛起數據庫

所以問題是:招標投標投訴按鈕這種反應,長輪詢掛起5-6項競價以1秒的時間間隔(我從服務器獲取Ajax的即時響應)的偉大工程,但第7(點擊)約16-22秒,然後完成請求。最後,所有內容都在數據庫中更新並完成,但在每5-6次出價響應/ ajax呼叫之後,大概持續16-22秒。

我怎麼能縮短這個時間,這一切都應該順利無論多少次的用戶投標,無滯後...

我使用Apache/PHP/MySQL的本地主機/ WAMP

我的代碼: 的index.php

<script type="text/javascript" charset="utf-8">    
var old_timestamp = <?php echo $old_timestamp;?>; //here i'm echoing last timestamp of   auction 

function waitForMsg(){ 
jq.ajax({ 
type: "POST", 
url: "http://localhost/bid/comet/poll.php", 
data: {"old_timestamp" : old_timestamp}, 
async: true, 
cache: false, 

success: function(data){ 
var json = eval('(' + data + ')'); 
if(json['msg'] != "") { 
jq('#comet_display').html(json['msg']); //here I show ID of which auction item was bidded 
} 
old_timestamp = json['old_timestamp']; 
setTimeout('waitForMsg()',100); 
}, 
error: function(XMLHttpRequest, textStatus, errorThrown){ 

setTimeout('waitForMsg()',1000); 
} 
}); 
} 

jq(window).load(function(){ 
waitForMsg(); 
jq("#a_loader").show(); 
    var url = "http://localhost/bid/auctions-ajax"; // the script where you handle the form input. 
    jq.ajax({ 
      type: "POST", 
      url: url, 
      data: {au978 : true}, 
      async:false, //to sem dodal za časovni zamik 
      success: function(data) 
      { 
      jq("#a_loader").hide(); 
      jq("#show-category").html(data); // show response from the php script.    
      }, 
      error: function(result) { 
       jq("#show-category").html("Sorry, something went wrong. Please try again later."); 
      } 
    }); 

}); 

function bid(id){ 

var url = "http://localhost/bid/comet/update-auction.php"; // the script where you handle the form input. 
var user_id=<?php echo $user_id;?>; //user id from session 
jq.ajax({ 
    type: "POST", 
    url: url, 
    data: {"auct_id" : id, "user_id" : user_id}, // serializes the form's elements. 
    success: function(data) 
    { 
     //it updates in user table its remaining number of bids 
    }, 
    error: function(XMLHttpRequest, textStatus, errorThrown){ 
     alert("Something went wrong. Click OK to refresh."); 

    } 
}); 
} 

</script> 

poll.php

<?php 

if ($_SERVER['REQUEST_METHOD'] === 'POST') { 
require_once($_SERVER['DOCUMENT_ROOT'] . 'bid/include/DEFINES.php'); 
require_once(CLASS_AUCTION); 
require_once(CLASS_DB); 

$a=new Auction(); 

$old_timestamp = $_POST['old_timestamp']; 
$bidded_id=0; 
$db=DB::getInstance(); 
$sql="SELECT timestamp, id FROM auction ORDER BY timestamp DESC LIMIT 1"; //desno doda tabelo kategorija 
$stmt=$db->db->prepare($sql) or die("Prepare Error"); 
$stmt->execute(); 
$result2=$stmt->fetchAll(PDO::FETCH_ASSOC); 
foreach ($result2 as $rez){ 
    $current_timestamp=$rez['timestamp']; 
    $bidded_id=$rez['id']; 
} 
$stmt->closeCursor(); 


    while($current_timestamp <= $old_timestamp){ 
    usleep(1000); 
    clearstatcache(); 
    $db=DB::getInstance(); 
    $sql="SELECT timestamp, id FROM auction ORDER BY timestamp DESC LIMIT 1";  
    $stmt=$db->db->prepare($sql) or die("Prepare Error"); 
    $stmt->execute(); 
    $result=$stmt->fetchAll(PDO::FETCH_ASSOC); 
    foreach ($result as $rez){ 
     $current_timestamp=$rez['timestamp']; 
     $bidded_id=$rez['id']; 
    } 
    $stmt->closeCursor(); 

} 
$response = array(); 
$response['msg'] = 'BID na avkciji: '.$bidded_id; 
$response['old_timestamp'] = $current_timestamp; 
echo json_encode($response); 
}else{ 
require_once($_SERVER['DOCUMENT_ROOT'] . 'bid/errors/404.html'); 
} 
?> 

和更新auction.php

<?php 
if ($_SERVER['REQUEST_METHOD'] === 'POST') { 
require_once($_SERVER['DOCUMENT_ROOT'] . 'bid/include/DEFINES.php'); 
require_once(CLASS_AUCTION); 
require_once(CLASS_USER); 
require_once(CLASS_DB); 
$u=new User(); 
$a=new Auction(); 
$auction_id=$_POST['auct_id']; 
$user_id=$_POST['user_id']; 
$date = new DateTime(); 
$timestamp=$date->getTimestamp(); 
$a->updateAuction($auction_id,$user_id,$timestamp/*,$bid_price,$bids_spent,$total_paid*/); 
$u->updateUserBids($user_id); 

}else{ 
require_once($_SERVER['DOCUMENT_ROOT'] . 'bid/errors/404.html'); 
} 
?> 

謝謝你看我的問題!

回答

0

好吧,我找到了一個解決方案修復了這個17-22秒的滯後問題。無論點擊多少次,現在幾乎是即時的。但我仍然不確定,如果這是長輪詢的最佳解決方案。

我發佈它,如果有人會有同樣的問題。

我變長輪詢功能在我poll.php這樣:

<?php 

if ($_SERVER['REQUEST_METHOD'] === 'POST') { 
require_once($_SERVER['DOCUMENT_ROOT'] . 'bid/include/DEFINES.php'); 
require_once(CLASS_AUCTION); 
require_once(CLASS_DB); 

$a=new Auction(); 
$db=DB::getInstance(); 
$sql="SELECT timestamp, id, last_username FROM auction ORDER BY timestamp DESC LIMIT 1";   
$response = array(); 
while(1) 
{ 
    $stmt=$db->db->prepare($sql) or die("Prepare Error"); 
    $stmt->execute(); 
    $result=$stmt->fetch(PDO::FETCH_ASSOC); 
    if (!empty($result)){ 
     $current_timestamp=$result['timestamp'];   
     $response['msg'] = 'New BID'; 
     $response['old_timestamp'] = $current_timestamp; 
     echo json_encode($response); 
     break; 
    } 
    sleep(3000); 
    clearstatcache(); 
} 
}else{ 
require_once($_SERVER['DOCUMENT_ROOT'] . 'bid/errors/404.html'); 
} 
?> 

現在我輪詢我的index.php像這樣:

<?php 
$db=DB::getInstance(); 
$sql="SELECT timestamp FROM auction ORDER BY timestamp DESC LIMIT 1";  
$stmt=$db->db->prepare($sql) or die("Prepare Error"); 
$stmt->execute(); 
$result2=$stmt->fetch(PDO::FETCH_ASSOC); 
$old_id=0; 
$last_timestamp=$result2['timestamp']; 
?> 
<script type="text/javascript" charset="utf-8">    
var last_timestamp = <?php echo $last_timestamp;?>; 
var old_timestamp=0; 

function waitForMsg(){ 
jq.ajax({ 
type: "POST", 
url: "http://localhost/bid/comet/poll.php", 
async: true, 
cache: false, 

success: function(data){ 
var json = eval('(' + data + ')'); 
if(old_timestamp==0 || last_timestamp==old_timestamp){ 

}else{ 
    if(json['msg'] != "") { 
    jq('#comet_display').html(json['msg']); 
} 
} 
old_timestamp = json['old_timestamp']; 

setTimeout('waitForMsg()',500); 
}, 
error: function(XMLHttpRequest, textStatus, errorThrown){ 

setTimeout('waitForMsg()',1000); 
} 
}); 
} 

jq(window).load(function(){ 
waitForMsg(); 

}); 
function bid(id){ 
var url = "http://localhost/bid/comet/update-auction.php"; //here I update auction and user's bids 
var user_id=<?php echo json_encode($user_id);?>; 
var user_name=<?php echo json_encode($user_name); ?>; 
jq.ajax({ 
    type: "POST", 
    async: true, 
    cache: false, 
    url: url, 
    data: {"auct_id" : id, "user_id" : user_id, "username" : user_name}, // serializes the form's elements. 
    success: function(data) 
    { 

     setTimeout('waitForMsg()',100); 
     var cnt = parseInt(jq(".db_bids").text()); 
     if (!isNaN(cnt)) 
     { 
      cnt--; 
      jq(".db_bids").text(String(cnt)); 
     }  
    }, 
    error: function(XMLHttpRequest, textStatus, errorThrown){ 
     alert("Something went wrong. Click OK to refresh."); 

    } 
}); 
} 
</script> 

我仍然在本地主機上開發這個&會看到這是如何在100多個用戶的真實服務器上運行的。 如果有人有更好更快的解決方案與數據庫中的長輪詢,請讓我知道:)

+0

您是否在更多客戶端上測試過它? – 2014-04-22 12:05:04

0

考慮改用WebSockets的。它旨在解決長輪詢問題。

+0

但會更快嗎?因爲我認爲我可能有數據庫問題......因爲完成了,只需要5次出價約20秒。在websockets中不會這樣嗎? – 2013-03-24 13:57:24

+0

而且crossbrowser兼容性是一個問題..只有cca。 60%的瀏覽器支持websocket ... [WebSocket支持](http://caniuse.com/websockets) – 2013-03-24 14:44:54

+1

這不應該是一個評論嗎? – 2013-07-27 17:16:43