Search code examples
phpjquerymysqlreal-timelong-polling

PHP MYSQL JQuery Long Polling - Not working as expected


My long polling implementation isn't working. Been having a very difficult time understanding where to look toward debugging said code.

Key Points

  • No Errors
  • Long polling working randomly (only responds to some changes in MySQL with no distinct pattern)
  • MySQL is updating correctly
  • I'm testing this via Localhost WAMP and two browsers with two different sessions

PHP Portion -

$path= $_SERVER[ 'DOCUMENT_ROOT']; 
$path .= "/config.php" ; 
require_once($path);

require_once(PHP_PATH . "/classes/user.php");

session_start(); 

require_once(PHP_PATH . "/functions/database.php");

// Return to Login if no Session
if(!isset($_SESSION['user'])){
    header("Location: /login");
    die();
}

$db = connectdatabase();

$timeout = 40;    

// if no post ids kill the script // Should never get here
if(!isset($_POST['post_ids'])){
    die();
}

if(!isset($_POST['timestamp'])){
    die();
}

$last_ajax_call = $_POST['timestamp'];
$post_ids = trim(strip_tags($_POST['post_ids']));
$id = $_SESSION['user']->getID();

// Check if there are posts from the last search that need to be updated with a comments or the like number has to be updated
$query = "SELECT posts.*, users.first_name, users.last_name, users.picture
        FROM posts
        LEFT JOIN users
        ON users.id = posts.user_id
        WHERE ((UNIX_TIMESTAMP(posts.date) > :last_ajax_call OR UNIX_TIMESTAMP(posts.last_modified) > :last_ajax_call) 
        AND posts.parent IN (:post_ids)) OR (posts.id IN (:post_ids) AND UNIX_TIMESTAMP(posts.last_modified) > :last_ajax_call)";

while ($timeout > 0) {
    $check_for_updates = $db->prepare($query);
    $check_for_updates->bindParam(':post_ids', $post_ids);
    $check_for_updates->bindParam(':last_ajax_call', $last_ajax_call);
    $check_for_updates->execute();
    $r = $check_for_updates->fetchAll();

    if(!empty($r)){
        // Get current date time in mysql format
        $unix_timestamp = time();

        // Cofigure result array to pass back
        $result = array(
            'timestamp' => $unix_timestamp,
            'updates' => $r
        );

        $json = json_encode($result);
        echo $json;
        return;
    } else {
        $timeout --;
        usleep( 250000 );
        clearstatcache();
    }
}
// you only get here if no data found
$unix_timestamp = time();

// Cofigure result array to pass back
$result = array(
    'timestamp' => $unix_timestamp
);

$json = json_encode($result);
echo $json;

JQuery Ajax -

function getUpdates(timestamp) {
            var post_ids = $("#newsfeed").find("#post_ids").attr('data-post-ids');
            var data = {'timestamp' : timestamp,
                        'post_ids' : post_ids};

            poll = $.ajax({
                    type: 'POST',
                    url: '/php/check_for_updates.php',
                    data: data,
                    async: true, /* If set to non-async, browser shows page as "Loading.."*/
                    cache: false,
                    success: function(data) {
                        try {
                            // put result data into "obj"
                            var obj = jQuery.parseJSON(data);
                            // put the data_from_file into #response
                            //$('#response').html(obj.data_from_file);
                            // repeat
                            console.log("SQL: " + obj['timestamp']);
                            setTimeout( function() {
                                // call the function again, this time with the timestamp we just got from server.php
                                getUpdates(obj['timestamp']);
                            }, 1000 );

                        } catch( e ) {
                            // repeat
                            // Get mysql formated date
                            var unix_timestamp = Math.floor(Date.now() / 1000);

                            console.log("JS:  " + unix_timestamp);
                            setTimeout( function() {
                                getUpdates(unix_timestamp);
                            }, 1000 );
                        }

                    }
                }
            );
        }

Solution

  • Thanks for all the help guys! I asked around a lot of people and got a bunch of great places to look to debug the code.

    I finally found the answer here -

    It looks like I the PHP checking for updates was blocking any updates from happening till the PHP stop checking for updates.