仅在更新时长轮询MySQL数据库

时间:2017-04-26 16:48:49

标签: php jquery mysql ajax long-polling

好吧,也许我在这里错过了一些东西,但对于我的生活,我无法理解这一点。我将在本地主机上运行这个Ajax长轮询脚本,所以我并不担心请求的数量,但我仍然想让它工作。

我正在运行一个得分管理员并显示记分牌。

在一个页面上,我有管理员,当你按下按钮时,它会在我的表“名册”的“得分”栏中添加10个点,其中等级等于按钮的等级。我没有任何问题更新数据库,我们只是设置全貌。

在第二页上。我有一个ajax调用,当前每秒触发并获取最近更新的行,并显示一个弹出窗口,通知用户10点只是添加到So-And-So的分数。

两个问题:

  1. 它每秒都在射击。
  2. 即使数据库尚未更新,它仍然会被解雇。
  3. 我知道我可以用ajax长轮询来做到这一点,但我无法弄清楚如何将所有部分正确连接在一起,以便只有在我们更新数据库时才会触发ajax调用。

    JS

    $(document).ready( function() {  
          pingScores();
        });
    
        var timestamp = null;
    
        function pingScores() {               
            $.ajax({ 
                type: "GET",
                url: "getUpdate.php?timestamp="+timestamp,
                cache: false,
                async: true,            
                success: function(data){
                    var json = eval('(' + data + ')');  
                    var notinyClass = json[2];
                    var notinyName = json[3];
                    //$.notiny({ text: notinyName+"<span class='addScore'> +10</span>", width: '100%', image: notinyClass }); - this is the popup API call that I am passing the class and the name to
    
                    timestamp = json["timestamp"];  
                    setTimeout("pingScores()", 1000);
                }
            });
        };
    

    PHP(getUpdate.php)

    <?php
    
     require "config.php"; //-- storing all login credentials elsewhere
    
     $db = mysql_connect($db_host, $db_user, $db_pass) or die(mysql_error());
     mysql_select_db($db_name) or die(mysql_error());
    
     $query = "SELECT * FROM roster ORDER BY last_updated DESC LIMIT 1";
     $result = mysql_query($query);
     $array = mysql_fetch_row( $result );
    
     echo json_encode($array);
    
     mysql_close();
    ?>
    

    DATABASE

    |id     | last_updated       | class | name  | score | active |
    |-------|--------------------|-------|-------|-------|--------|
    | 1     |2017-04-26 09:37:11 | alpha | Alpha | 10    | 1      |
    |-------|--------------------|-------|-------|-------|--------|
    | 2     |2017-04-26 09:32:59 | beta  | Beta  | 10    | 1      |
    |-------|--------------------|-------|-------|-------|--------|
    | 3     |2017-04-26 09:32:59 | delta | Delta | 10    | 1      |
    

    当数据库从ADD指向分数的一系列按钮更新时,PHP看起来像这样:

    <?php
        require "config.php";
    
        $conn = new mysqli($db_host, $db_user, $db_pass, $db_name);
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        } 
    
        $class = $_POST["class"];
    
        $sql = "UPDATE roster SET score = score + '10', last_updated = now() WHERE class = '".$class."'";
    
        if ($conn->query($sql) === TRUE) {
            echo "Updated data successfully\n";
        } else {
            echo $conn->error;
        }
    
        $conn->close();
    ?>
    

    我能找到的关于如何进行长轮询的每个教程都是从txt文件中提取数据,而关于如何从数据库中提取的指令并不是最清楚的。我希望得到一些关于如何做到这一点的澄清。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您只想在更新发生时显示通知。您需要存储最后显示的通知,例如:

var timestamp = null,
    lastNotificationIdentifier = '';

function pingScores() {               
    $.ajax({ 
        type: "GET",
        url: "getUpdate.php?timestamp="+timestamp,
        cache: false,
        async: true,            
        success: function(data){
            var json = eval('(' + data + ')');  
            var notinyClass = json[2];
            var notinyName = json[3];
            var localIdentifier = json.last_updated + json.id

            //check if we've displayed this record/timestamp before
            if (localIdentifier !== lastNotificationIdentifier) {

                //if not then go ahead and show the notification
                //$.notiny({ text: notinyName+"<span class='addScore'> +10</span>", width: '100%', image: notinyClass }); - this is the popup API call that I am passing the class and the name to

                //making sure to save some unique information about having shown this notification
                lastNotificationIdentifier = localIdentifier;
            }

            timestamp = json["timestamp"];  
            setTimeout("pingScores()", 1000);
        }
    });
};

您只能使用last_updated列作为唯一标识符,以确保不会多次显示通知,但这在技术上并不唯一,因为您可以在其中更新两列同一秒。这就是我使用时间戳和记录ID的混合物的原因。

就这个每秒运行一次的AJAX而言,那就是你设置超时的时间:

setTimeout("pingScores()", 1000);

超时延迟以毫秒为单位,如果您想要使用5000 5秒钟。您可能会看到快速加载时间,因为它在本地运行,因此每个请求加载所需的时间可能可以忽略不计。