2013-03-23 6 views
3

Я разрабатываю живой аукцион сайт, с в режиме реального времени системы торгов. Я использую LONG POLLING, когда пользователь делает ставку на товар. Я выбрал длинный опрос, потому что WebSockets еще не очень поддержаны, и NODEJS сложно для меня реализовать прямо сейчас. Таким образом, я застрял в этом длинном опросе simle ajax, который отлично подходит для пяти заявок.LONG ОПРОС (в PHP) начинает висеть после 5 запросов к базе данных

Так что проблема: Торгов отлично работает в течение 5-6 ст ставка в 1-секундных интервалах (я получаю мгновенный ответ от сервера-Ajax), но седьмой (щелчок) на кнопке ставки этого ответ длиной опрос вешает в течение примерно 16-22 секунд, а затем завершает запрос. В конце все обновляется в базе данных и завершается, но после каждых 5-6 запросов ставок/ajax call hangss в течение примерно 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

ОК, Я нашел решение, которое исправляет эту проблему с задержкой LAG-HANG 17-22 секунд. Теперь это почти мгновенно, независимо от того, сколько раз вы нажимаете. Но я все еще не уверен, если это лучшее решение длинных опросов.

Я отправляю его, если у кого-то будет такая же проблема.

Я изменил LONG функцию ОПРОСА в моем 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> 

Я все еще разрабатываю это на localhost & увидит, как это ведет себя на реальном сервере со 100+ пользователями. Если у кого-то есть лучшее и быстрое решение с LONG POLLING из баз данных, пожалуйста, дайте мне знать :)

+0

Вы тестировали его на большее количество клиентов? –

0

Рассмотрите возможность перехода на WebSockets. Он был разработан, чтобы исправить длинную проблему опроса.

+0

Но будет быстрее?Потому что я думаю, что у меня может быть проблема с базой данных ... Потому что все будет сделано, просто займет 5 ставок около 20 секунд. Разве это не было бы так же в websockets? –

+0

А также совместимость с кроссбраузером - это проблема .. Только cca. 60% браузеров поддерживают websockets ... [Поддержка WebSocket] (http://caniuse.com/websockets) –

+1

Разве это не комментарий? –