使用PHP和AJAX的实时应用程序往往会挂起,而且不尊重刷新间隔


Real time application with PHP and AJAX tends to hang and not respect the refresh interval

我使用PHP和AJAX编写了一个小部件,它每10秒从MySQL数据库获取实时信息。问题是,在多次成功运行之后,它往往会出现bug。它不再遵守10秒的间隔,甚至小部件末尾的时间计数器也倾向于"跳"几秒。这些文件如下所示:

MySQL类:database.class.php文件包含一个函数,它可以帮助我使用PDO连接到MySQL。

Device类:(如下所示)包含一个函数,它帮助我从数据库中检索最后10个条目。readings_$id(其中$id是一个数字)表经常更新。

require_once dirname(__FILE__).'/database.class.php';
class Device extends Database {
    public function get_last_ten_reads($id){
        $table = "readings_".$id;
        try {
            $statement = $this->connection->prepare("SELECT * FROM $table ORDER BY server_time DESC LIMIT 10");
            //Execute the statement:
            $statement->execute();
            //Get the result:
            $result = $statement->fetchAll(PDO::FETCH_ASSOC);
            return $result;
        } catch (PDOException $exception) {
            echo $exception -> getMessage();
        }
    }
}

小部件文件:(附在下面)创建一个新的设备对象,从会话变量中获取id,然后使用上面的mysql函数获取最后10个条目。在此完成后,我将对象设置为null,因为该操作将在10秒后再次重复。init.core.php文件包含session_start,重要的包含类(如数据库),重要的应用常量(如$id_device存储在一个SESSION中)。

<?php include_once($_SERVER['DOCUMENT_ROOT'].'/core/init.core.php');?>
<?php $device    = new Device();?>
<?php $id_device = $_SESSION['account']['id']; ?>
<?php $entries   = $device->get_last_ten_reads($id_device); ?>
<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title">Last 10 readings:</h3>
    </div>
    <div class="table-responsive">
        <table class="table table-hover">
            <thead>
                <tr class="active">
                    <th>Id Sensor:</th>
                    <th>Sensor Time:</th>
                    <th>Server Time:</th>
                    <th>Value:</th>
                    <th>Battery level:</th>
                </tr>
            </thead>
            <tbody>
                <?php              
                foreach ($entries as $row) { 
                ?>
                    <tr>
                        <td><?php echo $row['id_sensor'];?></td>
                        <td><?php echo $row['sensor_time'];?></td>
                        <td><?php echo $row['server_time'];?></td>
                        <td><?php echo $row['value'];?></td>
                        <td><?php echo $row['battery_level'];?></td>
                    </tr>  
                <?php } ?>
            </tbody>
        </table>
    </div>
    <?php $device = null;?>
    <div class="panel-footer">
        <small>Last updated at: 
            <?php date_default_timezone_set('Europe/London');
            $date = date('Y-m-d H:i:s');
            echo $date ?>
        </small>
    </div>
</div>
jQuery/AJAX脚本:
function get_reads(){
    var reads = $.ajax({
        type: "POST",
        url: ".././cards/widget.php",
        async: false,
        cache: false
    }).success(function(){
        setTimeout(function(){get_reads();}, 10000);
    }).responseText;
    $('.bootcards-list').html(reads);
}
setInterval(function(){get_reads();}, 10000);
最后是index.php文件:
<?php
    include ('core/init.core.php');
    include ('header.php');
?>
<!-- Begin page content -->
<div class="container">
    <div class="row">
        <div class="col-sm-12 bootcards-list">
            <?php include('cards/widget.php');?>
        </div>
        <script type="text/javascript" src="js/ajax.js"></script>
    </div> <!-- /row -->
</div>
<?php
    include ('footer.php');
?>

脚本在开始时工作正常,但随后它开始出现故障(挂起或有bug)。甚至小部件底部显示最后一次从数据库获取信息的时间也会以任意秒数刷新,这不是我在AJAX脚本中给出的时间。以前有人遇到过这个问题吗?

p。S:很抱歉让你看了这么长时间。

请,拉杜

它不尊重10秒,因为这个模式:

function get_reads() {
    AJAX.post
          .success(function() {
              get_reads(); // with a 10 seconds delay from setTimeout
          })
}

代码将在AJAX.post响应后10秒执行get_reads,而不是在您最后调用get_reads之后。所以首先要考虑修复这个

第二个问题,挂起,是由于你把递归函数和setInterval混在一起造成的。

如果您阅读文档,您会发现setInterval重复调用该函数,每X毫秒(10000ms -> 10秒)一次。所以你每隔10秒通过setInteval运行get_reads,每次调用它时,你也会通过get_reads本身启动一个无限递归循环。

坚持setInterval并删除递归调用(setTimeout(function(){get_reads();}, 10000);),您将解决这两个问题。