我正在使用实时出价系统开发实时竞价网站。当用户对商品出价时,我使用 LONG POLLING 。我选择了长轮询,因为 WebSockets 尚未得到很好的支持, NODEJS 对于我来说现在很难实现。所以我坚持使用这个simle ajax长轮询,这适用于大约五个出价。
所以问题是:以1秒的间隔投标效果非常适合5-6件商品出价(我从服务器-ajax获得即时回复),但第7次(点击)出价按钮此回复-long polling挂起大约16-22秒,然后完成请求。最后,所有内容都在数据库中更新并完成,但在每5-6个出价响应/ ajax呼叫挂起约16-22秒后。
我怎样才能减少这段时间,无论用户出价多少次,一切都应该顺利进行,没有滞后......
我在localhost / wamp上使用Apache / PHP / MySql
我的代码: 的的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');
}
?>
和update-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 :(得分:0)
考虑切换到WebSockets。它旨在解决长轮询问题。
答案 1 :(得分:0)
好的,我找到了解决方案,修复了这个17-22秒的LAG-HANGING问题。现在它几乎是即时的,无论你点击多少次。但我仍然不确定,如果这是长期民意调查的最佳解决方案。
如果有人遇到同样的问题,我会张贴它。
我已将poll.php中的LONG POLLING功能更改为:
<?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&amp;将看到这在具有100多个用户的真实服务器上的行为。 如果有人有更好更快的解决方案并且数据库中有LONG POLLING,请告诉我们:)