Reputation: 1910
I've been trying for the last two days to get this to work with no luck. It executes one time, but fails to continue to update after the initial load. The function does not automatically update, nor does it relaunch after 30 seconds. The code seems fine to me but obviously there is some gap of knowledge I have regarding long-polling which is causing this not to work. If anyone has a moment I'd appreciate it if you could comb over this and tell me what it is I'm doing incorrectly. Any help is appreciated, thank you.
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"));
});
PHP (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;
?>
Upvotes: 0
Views: 2139
Reputation: 12705
I think once you receive a response, the browser will not and should not keep the connection open. Also it depends a lot upon the browser you are using and headers you are sending.
I'm not much of a PHP guy, but the Header should contain Connection: Keep-alive to keep the connection open
.
Also going by the various tests I conducted.
IE will not keep the existing connection open but will open 2 connections simultaneously and will keep the second one open and will close the first one.
Chrome behaves nicely send 2 requests (one for favicon) but keeps the connection open.
Mozilla sends only one request and keeps it open. Are you using IE9 to test this?
Upvotes: 0
Reputation: 1507
The major problem I think you're having is in your assuming that complete: poll will use the passed-in parameter pid from the current call. Try this.
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"));
});
All that said, if you have many posts you're checking updates for, you might consider bundling these calls up and calling once per page every 30 seconds (and return an array of post updates) instead of once per post per page every 30 seconds. (My extra two cents.)
Edit: Added the timeout mentioned. Left it out the first time.
Upvotes: 0