简体   繁体   English

如何将其置于实时状态?我已经把(async:True)但它不起作用

[英]How do I put this on Real-Time? I already put (async: True) but it doesnt work

I finally made it working with AJAX but the problem is, it's not real-time whenever I change some data in phpMyAdmin, I need to refresh it on the website. 我终于使用了AJAX,但问题是,每当我在phpMyAdmin中更改一些数据时都不是实时的,我需要在网站上刷新它。

Here's my code: ajax.js 这是我的代码: 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) {

        }
    });
});



Here's my code in data.php 这是我在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);

?> ?>

How can I get it to real-time without refreshing the page? 如何在不刷新页面的情况下实现它? Please help, thanks! 请帮忙,谢谢!

Instead of polling, you can use server-sent-events, which does not put as much strain on the server as data is only sent if a new event has happened (like a new row). 您可以使用服务器发送事件而不是轮询,这不会给服务器带来太多压力,因为只有在发生新事件(例如新行)时才会发送数据。 More can be found out about them here: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events 有关它们的更多信息,请访问: https//developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

Here is an example, as the one in the link is not that good. 这是一个例子,因为链接中的那个不是那么好。

The result will look like the following gif: 结果将类似于以下gif:

在此输入图像描述

chart.html 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>

Then the event loop, note that this is not an infinite loop nor do you need to maintain it, it will get created once a client connects and exit once the client disconnects. 然后事件循环,请注意这不是一个无限循环,也不需要维护它,一旦客户端连接并在客户端断开连接后退出,它将被创建。

sse.php 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);
}

Hope it helps, avoid polling its 2018! 希望它有所帮助,避免轮询其2018年!

What you can do is set a timer, then execute your ajax call every n seconds/minutes, but this is expensive if your data is too large/big. 您可以做的是设置一个计时器,然后每n秒/分钟执行一次ajax调用,但如果您的数据太大/太大,这是很昂贵的。 I recommend using web socket , as this will only one time open a bridge connection from your server side to your client side, then it will just cost minimal resources to transfer data between. 我建议使用Web套接字 ,因为这只会一次打开从服务器端到客户端的桥接连接,然后只需要很少的资源来传输数据。

ref for php web socket: http://socketo.me/ ref for php web socket: http//socketo.me/

Or just do the timer thing with your javascript: 或者只是用你的javascript做计时器:

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

there are two ways to do this (there is much more, I know). 有两种方法可以做到这一点(还有更多,我知道)。 the first is you create a javascript function that executes this request from time to time, (this will cost processing). 首先是你创建一个不时执行这个请求的javascript函数(这将花费处理成本)。

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

the other is you study something that is fashionable, RXJS, a javascript technology, you will need a good time to study. 另一个是你学习时尚的东西,RXJS,一个javascript技术,你需要一个学习的好时机。 If it is only for study, I recommend FireBase (google technology) in which it provides this database in real time 如果它仅用于研究,我推荐FireBase(谷歌技术),它实时提供此数据库

RxJs documentation RxJs文档

Simple Ajax implementation with RxJS 使用RxJS进行简单的Ajax实现

And always remember to search before posting anything, maybe you find the answer that you are looking for, good study =) 并且总是记得在发布任何内容之前搜索,也许你找到了你正在寻找的答案,好学习=)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM