长轮询(在PHP)开始挂后5请求数据库数据库、长轮询、PHP

2023-09-10 17:37:42 作者:烟雨醉巷

我开发的现场拍卖网站,是实时招投标制。我使用的长轮询当资料的用户出价。我选择了长轮询,因为的WebSockets 还没有非常支持和 NODEJS 是复杂,我立即实施。所以,我坚持这个笑着AJAX长轮询,其中约五竞标的伟大工程。

I'm developing live auction site, with real-time bidding system. I'm using LONG POLLING when user bids on item. I've chose long polling because WebSockets are not yet very supported and NODEJS is to complicated for me to implement right now. So I'm stuck with this simle ajax long polling, which works great for about five bids.

所以,问题是:出价5-6项目投标间隔为1秒(我从服务器阿贾克斯即时反应)的伟大工程,但第7(单击)投标按钮这种反应-long投票挂起约16-22秒,然后完成请求。在结束一切都在数据库中更新和完成,但每隔5-6投标响应/ Ajax调用hangss约16-22秒后。

So the problem is: Bidding works great for 5-6 item bids in 1 second intervals (I get instant response from server-ajax), but the 7th (click) on bid button this response-long polling hangs for about 16-22 seconds and then completes the request. At the end everything is updated in database and completed but after every 5-6 bids response/ajax call hangss for about 16-22 seconds.

我怎么能缩短这个时间,一切都应该能够顺利进行,无论多少次的用户出价,而不滞...

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

我的code: 的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');
}
?>

感谢您查看我的问题!的

推荐答案

好吧,我已经找到一个解决办法它修复了这个17-22秒LAG挂的问题。现在,几乎是一瞬间,你不管有多少次点击。但我还是不知道,如果这是长轮询的最佳解决方案。

Ok, I have find a solution which fixes this 17-22 seconds LAG-HANGING problem. Now it's almost instant, regardless how many times you click. But I'm still not sure, if this is the best solution of long polling.

我张贴,如果有人有同样的问题。

I'm posting it, if someone would have the same problem.

我变长轮询功能在我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多个用户。 如果任何人有更好更快的解决方案从数据库长轮询,请让我知道:)

I'm still developing this on localhost & will see how this behaves on real server with 100+ users. If anyone have better and faster solution with LONG POLLING from databases, please let me know :)