【问题标题】:How do I put this on Real-Time? I already put (async: True) but it doesnt work我如何把它放在实时上?我已经放了(异步:真)但它不起作用
【发布时间】:2018-08-11 08:22:18
【问题描述】:

我终于让它与 AJAX 一起工作,但问题是,每当我更改 phpMyAdmin 中的一些数据时,它都不是实时的,我需要在网站上刷新它。

这是我的代码:ajax.js

$(document).ready(function() {
    $.ajax({
        url: "http://localhost/projectZeus/private/data.php",
        method: "GET",
        async: true,
        success: function(data) {
            var energy = [];

            for(var i in data) {
                energy.push(data[i].energyPercent);
            }   

            var chartdata = {
                labels: ["Jan", "Feb", "Mar", "Apr", "May"],
                datasets: [{
                    label: "Harvested",
                    lineTension: 0.3,
                    backgroundColor: "rgba(2,117,216,0.2)",
                    borderColor: "rgba(2,117,216,1)",
                    pointRadius: 6,
                    pointBackgroundColor: "rgba(2,117,216,1)",
                    pointBorderColor: "rgba(255,255,255,0.8)",
                    pointHoverRadius: 8,
                    pointHoverBackgroundColor: "rgba(2,117,216,1)",
                    pointHitRadius: 20,
                    pointBorderWidth: 2,
                    data: energy
                }]
            };

            var ctx = $("#AreaChart");

            var lineChart = new Chart(ctx, {
                type: 'line',
                data: chartdata
            });
        },
        error: function(data) {

        }
    });
});



这是我在 data.php

中的代码
<?php
require_once('initialize.php');

header('Content-Type: application/json');
global $db;

$sql = "SELECT energyPercent FROM energy";
$result = mysqli_query($db, $sql);

$data = array();
foreach($result as $row) {
    $data[] = $row;
}
mysqli_free_result($result);

echo json_encode($data);

?>

如何在不刷新页面的情况下使其实时?请帮忙,谢谢!

【问题讨论】:

    标签: javascript php ajax chart.js real-time


    【解决方案1】:

    您可以使用 server-sent-events 代替轮询,它不会像仅在发生新事件(例如新行)时才发送数据那样对服务器造成太大压力。可以在这里找到更多关于它们的信息:https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

    这是一个示例,因为链接中的示例不太好。

    结果将如下图所示:

    chart.html

    <html>
    
    <head>
        <meta charset="UTF-8">
        <title>Server-sent events demo</title>
        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    </head>
    
    <body>
    
        <div id="chart_div"></div>
    
        <button>Close the connection</button>
    
        <script>
            // google chart function
            function chart(chart_data) {
                google.charts.load('current', { packages: ['corechart', 'line'] });
                google.charts.setOnLoadCallback(drawBasic);
    
                function drawBasic() {
    
                    var data = new google.visualization.DataTable();
                    data.addColumn('number', 'X');
                    data.addColumn('number', 'Dogs');
    
                    data.addRows(chart_data);
    
                    var options = {
                        hAxis: {
                            title: 'Time'
                        },
                        vAxis: {
                            title: 'Popularity'
                        }
                    };
    
                    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    
                    chart.draw(data, options);
                }
            }
    
            // stop button
            var button = document.querySelector('button');
    
            // the rest is the EventSource, simplez.. 
            var evtSource = new EventSource('sse.php', { withCredentials: true });
    
            evtSource.onopen = function() {
                chart([])
            }
    
            evtSource.onmessage = function(e) {
                chart(JSON.parse(e.data))
            }
    
            evtSource.onerror = function() {
                console.log("EventSource failed.");
            }
    
            button.onclick = function() {
                console.log('Connection closed');
                evtSource.close();
            }
    
            /**
            * or you could use addEventListener's to listen to specific events, like event: chartdata (or incase you wanted to send multiple events in the same stream)
            */
            //   evtSource.addEventListener("ping", function(e) {
            //      // do somthing with JSON.parse(e.data)
            //   }, false);      
    
            //   evtSource.addEventListener("message", function(e) {
            //      // do somthing with JSON.parse(e.data)
            //   }, false);
        </script>
    </body>
    
    </html>
    

    然后是事件循环,注意这不是一个无限循环,也不需要维护它,它会在客户端连接时创建并在客户端断开连接时退出。

    sse.php

    <?php
    // no normal requests
    if ($_SERVER['HTTP_ACCEPT'] !== 'text/event-stream') {
        exit();
    }
    
    // make session read-only
    session_start();
    session_write_close();
    
    // disable default disconnect checks
    ignore_user_abort(true);
    
    // set headers for stream
    header("Content-Type: text/event-stream");
    header("Cache-Control: no-cache");
    header("Access-Control-Allow-Origin: *");
    
    // a new stream or an existing one
    $lastEventId = intval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : 0);
    
    if ($lastEventId === 0) {
        // resume from a previous event
        $lastEventId = intval(isset($_GET["lastEventId"]) ? $_GET["lastEventId"] : 0);
    }
    
    echo ":".str_repeat(" ", 2048)."\n"; // Padding for IE
    echo "retry: 2000\n";
    
    // query initial data, or select by event id
    $data = [
        [0, 0],
        [1, 5],
        [2, 15],
        [3, 45],
        [4, 34],
        [5, 21],
    ];
    
    // mock we at event 6
    $lastEventId = 6;
    
    // start stream
    while (true) {
    
        // user disconnected, kill process
        if (connection_aborted()) {
            exit();
        } else {
    
        // force an update, normally you would assign ids to your events/data
        $latestEventId = $lastEventId+1;
    
        //
        if ($lastEventId < $latestEventId) {
    
            // generate some data, use array_shift() before to limit array leght whilst rolling
            $data[] = [$latestEventId, rand(0, 100)];
    
            echo "id: " . $latestEventId . "\n";
            echo "event: message\n";
            echo "data: ".json_encode($data)."\n\n";
    
            $lastEventId = $latestEventId;
        } else {
            echo "event: ping\n";
        }
      }
    
      // flush buffer
      ob_flush();
      flush();
    
      // 2 second sleep
      sleep(2);
    }
    

    希望它有所帮助,避免在 2018 年投票!

    【讨论】:

    【解决方案2】:

    您可以做的是设置一个计时器,然后每 n 秒/分钟执行一次 ajax 调用,但如果您的数据太大/太大,这会很昂贵。我推荐使用 web socket,因为这只会打开一次从服务器端到客户端的桥接连接,然后在它们之间传输数据只需花费最少的资源。

    php web socket的参考:http://socketo.me/

    或者只是用你的javascript做计时器:

    setInterval(function() {
       //call your ajax function here
    }, 5 * 1000) //1000 millisecond = 1 second, so multiply by 5 for 5 seconds
    

    【讨论】:

    • 至少你提到了 websockets,因为不需要 2 路数据,服务器也发送了事件。
    • 感谢您的澄清,也许我应该阅读更多关于它是如何工作的。呵呵。
    【解决方案3】:

    有两种方法可以做到这一点(我知道还有更多)。第一个是您创建一个不时执行此请求的 javascript 函数(这将花费处理)。

    function functionAjax () {
        console.log ('Running');
    }
    var interval = setInterval (Ajax function, 3000);
    

    另一个是你学的东西很时髦,RXJS,一种javascript技术,你需要好好学习。 如果只是为了学习,我推荐FireBase (google technology) in which it provides this database in real time

    RxJs documentation

    使用 RxJS 实现简单的 Ajax

    并且永远记得在发布任何东西之前搜索,也许你会找到你正在寻找的答案,好好学习=)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-05
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 2022-01-16
      相关资源
      最近更新 更多