I have a simple long poll request on my website to check if there are any new notifications available for a user. As far as the request goes, everything seems to work flawlessly; the request is only fulfilled once the database is updated (and a notification has been created for that specific user), and a new request is sent out straight after.
The Problem
What I have noticed is that when the request is waiting for a response from the database (as long polls should), all other requests to the server will also hang with it - whether it be media files, AJAX requests or even new pages loading. This means that all requests to the server will hang until I close my browser and reopen it.
What is even stranger is that if I visit another one of my localhost
sites (my long poll is on a MAMP virtualhost site, www.example.com
), their is no problem and I can still use them as if nothing has happened - despite the fact they're technically on the same server.
My Code
This is what I have on my client side (longpoll.js
):
window._Notification = {
listen: function(){
/* this is not jQuery's Ajax, if you're going to comment any suggestions,
* please ensure you comment based on regular XMLHttpRequest's and avoid
* using any suggestions that use jQuery */
xhr({
url: "check_notifs.php",
dataType: "json",
success: function(res){
/* this will log the correct response as soon as the server is
* updated */
console.log(res);
_Notification.listen();
}
});
}, init: function(){
this.listen();
}
}
/* after page load */
_Notification.init();
And this is what I have on my server side (check_notifs.php
):
header("Content-type: application/json;charset=utf-8", false);
if(/* user is logged in */){
$_CHECKED = $user->get("last_checked");
/* update the last time they checked their notifications */
$_TIMESTAMP = time();
$user->update("last_checked", $_TIMESTAMP);
/* give the server a temporary break */
sleep(1);
/* here I am endlessly looping until the conditions are met, sleeping every
* iteration to reduce server stress */
$_PDO = new PDO('...', '...', '...');
while(true){
$query = $_PDO->prepare("SELECT COUNT(*) as total FROM table WHERE timestamp > :unix");
if($query->execute([":unix" => $_CHECKED])){
if($query->rowCount()){
/* check if the database has updated and if it has, break out of
* the while loop */
$total = $query->fetchAll(PDO::FETCH_OBJ)[0]->total;
if($total > 0){
echo json_encode(["total" => $total]);
break;
}
/* if the database hasn't updated, sleep the script for one second,
* then check if it has updated again */
sleep(1);
continue;
}
}
}
}
/* for good measure */
exit;
I have read about NodeJS and various other frameworks that are suggested for long-polling, but unfortunately they're currently out of reach for me and I'm forced to use PHP. I have also had a look around to see if anything in the Apache configuration could solve my problem, but I only came across How do you increase the max number of concurrent connections in Apache?, and what's mentioned doesn't seem like it would be the problem considering I can still use my other localhost
website on the same server.
Really confused as to how I can solve this issue, so all help is appreciated,
Cheers.