John Davidson

ajax - PHP Long Polling Script Not Ending

0 comments
Message:


I have searched far and wide for a working answer and despite no shortage of questions on this issue, have not yet found one.


I have a php script which checks the db for updates initiated by an ajax call with setTimeout. The page is like a game lobby where users can create, join or leave a game. When they do, the listening ajax function is aborted while the update occurs and then resumes straight after. This works perfectly with no delays or lag when I test it as a solo user but as soon as another user is on the page, the php script seems to hang up and not want to exit out of the loop, with nothing happening on the front end until it has timed out.


I have added session_write_close, ob_flush and flush(), tried it with and without session_start, all to no avail. I'm sure websockets are better suited but they are currently not an option.


AJAX


var hear,
checking;
function listen(){
hear = $.ajax({
url: "check.php?last=0",
success: function(data){
//do some stuff
checking = setTimeout({listen()}, 3000);
}
})
}
//NOW WHEN USER CLICKS JOIN FOR EXAMPLE-
clearTimeout(checking);
hear.abort();
//Perform a different ajax call to update db, then resume listen()

CHECK.php


require_once("../abc/connection.php");  // connect to db

//*******START OF VARIOUS TRIED SETTINGS
session_start();
$id = $_SESSION['id'];
session_write_close();
ignore_user_abort(1);
set_time_limit(40);
ini_set('zlib.output_compression', 0);
ini_set('implicit_flush', 1);
//*********END OF VARIOUS TRIED SETTINGS

$last = isset($_GET['last']) ? mysqli_real_escape_string($_GET['last']) : 0 ;
$true = 0;
while($true < 10){
$true++;
$str = " "; //tried this line and below to help force script acknowledgement of ajax abortion
echo $str;
if(connection_status() != CONNECTION_NORMAL){
echo str_repeat($str, 1024); // In case of minimum output requirement 1KB
ob_flush();
flush();
break;
}
$sql = mysqli_query($con, "SELECT * FROM games WHERE id > $last");
if(mysqli_num_rows($sql) > 0){
echo "Change detected";
break;
}else{
mysqli_free_result($sql);
sleep(3);
}
}

At this point I'm almost ready to revert back to just making the ajax call every 3 seconds. Very grateful for any help. Thanks



My Answer:
It looks like you are trying to implement long polling in your PHP script, but there are a few issues that may be causing the script to hang up.

First, in your AJAX function, you are calling `setTimeout({listen()}, 3000);` which should be `setTimeout(listen, 3000);`. The way you have it written now, it will immediately call the `listen()` function instead of waiting for the timeout.

Second, in your PHP script, you are using `sleep(3)` which may be causing the script to hang up. Instead of using `sleep`, you can try using `usleep` which is more suitable for long polling.

Here is an updated version of your PHP script:

php
require_once("../abc/connection.php"); // connect to db

$last = isset($_GET['last']) ? mysqli_real_escape_string($con, $_GET['last']) : 0 ;
$true = 0;
while($true < 10){
$true++;
$str = " "; //tried this line and below to help force script acknowledgement of ajax abortion
echo $str;
if(connection_status() != CONNECTION_NORMAL){
echo str_repeat($str, 1024); // In case of minimum output requirement 1KB
ob_flush();
flush();
break;
}
$sql = mysqli_query($con, "SELECT * FROM games WHERE id > $last");
if(mysqli_num_rows($sql) > 0){
echo "Change detected";
break;
}else{
mysqli_free_result($sql);
usleep(3000000); // sleep for 3 seconds
}
}


Make sure to replace `connection.php` with the correct path to your database connection file.

Also, make sure that your database connection is properly closed after each query to prevent any connection issues.

Hopefully, these changes will help resolve the issue with your long polling script. Let me know if you have any further questions.

Rate this post

3 of 5 based on 6567 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us