在过去的两天里,我一直在努力让它工作,但没有运气。它执行一次,但在初始加载后无法继续更新。该功能不会自动更新,也不会在 30 秒后重新启动。代码对我来说似乎很好,但显然我在长轮询方面存在一些知识差距,这导致它不起作用。如果有人有时间,如果您能梳理一下并告诉我我做错了什么,我将不胜感激。任何帮助不胜感激,谢谢。
JavaScript/jQuery
function poll(pid){
var dataString = 'pid=' + pid;
$.ajax({type: 'GET', url: 'http://localhost:8888/mysite/execs/vote_count.php', data: dataString, async: true, cache: false, success: function(data){
var post = $('#' +pid);
var post_children = post.children();
var upvotes = post_children.find('.upvotes');
var downvotes = post_children.find('.downvotes');
downvotes.text("-" + data.downvotes);
upvotes.text("+" + data.upvotes);
}, dataType: "json", complete: poll, timeout: 30000 });
};
$(".post").each(function(){
poll($(this).attr("id"));
});
菲律宾比索 (vote_count.php)
<?php
$hostname = 'localhost';
$username = 'root';
$password = 'root';
$database = 'database';
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT * FROM vote WHERE post = :pid AND rating = 'votedown'");
$pid = $_GET['pid'];
$stmt->bindParam(':pid', $pid, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll();
}
catch(PDOException $e)
{
echo $e->getMessage();
}
$stmt->execute();
$downvotes = $stmt->rowCount();
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT * FROM vote WHERE post = :pid AND rating = 'voteup'");
$pid = $_GET['pid'];
$stmt->bindParam(':pid', $pid, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll();
}
catch(PDOException $e)
{
echo $e->getMessage();
}
$stmt->execute();
$upvotes = $stmt->rowCount();
$arr = array("downvotes"=>$downvotes,"upvotes"=>$upvotes);
echo json_encode($arr);
$dbh = null;
?>
我认为您遇到的主要问题是假设完成:轮询将使用来自当前调用的传入参数 pid。 试试这个。
function poll(pid){
var dataString = 'pid=' + pid;
$.ajax({type: 'GET',
url: 'http://localhost:8888/mysite/execs/vote_count.php',
data: dataString,
async: true,
cache: false,
success: function(data){
var post = $('#' +pid);
var post_children = post.children();
var upvotes = post_children.find('.upvotes');
var downvotes = post_children.find('.downvotes');
downvotes.text("-" + data.downvotes);
upvotes.text("+" + data.upvotes);
},
dataType: "json",
complete: function(xhr, status){
setTimeout(function(){poll(pid);}, 30000);
},
timeout: 30000
});
}
$(".post").each(function(){
poll($(this).attr("id"));
});
综上所述,如果您有许多帖子正在检查更新,您可以考虑将这些调用捆绑在一起,每 30 秒每页调用一次(并返回一系列帖子更新),而不是每 30 秒每页每页每个帖子一次。 (我额外的两分钱。
编辑:添加了提到的超时。 第一次就把它排除在外。
我认为一旦您收到响应,浏览器就不会也不应该保持连接打开状态。此外,这在很大程度上取决于您使用的浏览器和您发送的标头。
我不太喜欢 PHP,但标头应该包含 Connection: Keep-alive to keep the connection open
.
还通过我进行的各种测试。
-
IE 不会使现有连接保持打开状态,但会同时打开 2 个连接,并使第二个连接保持打开状态并关闭第一个连接。
-
Chrome 表现良好,可以发送 2 个请求(一个用于网站图标),但保持连接打开。
-
Mozilla 只发送一个请求并保持打开状态。您是否正在使用IE9来测试此内容?