【问题标题】:long polling with PHP and AJAX... almost there使用 PHP 和 AJAX 进行长轮询......几乎就在那里
【发布时间】:2011-05-21 23:13:16
【问题描述】:

我正在处理一个学校项目。该项目的基本理念是,我们有一些 arduino 盒子将一些传感器数据发送到 mysql 数据库,并且我们有一个显示它的网站。传感器数据每 6 秒发送一次。

我对 PHP 没有太多经验。但我正在修补我的方式,一步一步地学习..牛仔风格? =)

html/ajax/css:

    <!DOCTYPE html>
<html>
<head>
    <title>Arduino event poller</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>

    <style type = "text/css" media="screen">
        body{ font:13px/1.5 "helvetica neue", helvetica, arial, san-serif; background:#FFF; }
        #main{ width:430px; height: 300px; display:block; padding:10px 0; float: left; overflow: auto;}
        .event { display:block; background: #ececec; width:380px; padding:10px; margin:10px; overflow:hidden; text-align: left; }  
        .event img { display:block; float:left; margin-right:10px; }  
        .event p { font-weight: bold; }
        .event img + p { display:inline; }
        .patient-name { display:inline; color: #999999; font-size: 9px; line-height:inherit; padding-left: 5px; }
        .event-text{ color: #999999; font-size: 12px; padding-left: 5px; }
        .event-timestamp{ color: #000; padding-left: 5px; font-size: 9px;}
    </style>

    <script type="text/javascript" charset="utf-8">

        var timeStamp = null;

        /* Simple helper to add some divs.*/
        function addevents(patientroom, patientname, eventtyp, timestamp)
        {
            $("#main").append(
                "<div class='event'>"
                "<p>" + patientroom + "</p>"
                "<p class='patient-name'>" + patientname + "</p>"
                "<p class='event-text'>" + eventtyp + "</p>"
                "<p class='event-timestamp'>" + timestamp + "</p>"
                "</div>"
                );
        }

        /*This requests the url "getevents.php" When it complete*/
        function waitForEvents()
        {
            $.ajax({
                type: "GET",
                url: "getevents.php?timeStamp=" + timeStamp,

                async: true, /* If set to non-async, browser shows page as "Loading.."*/
                cache: false,
                timeout:50000, /* Timeout in ms */

                success: function(data, textStatus, jqXHR) /* called when request to getevents.php completes */
                {
                    addevents(data.patientroom, data.patientname, data.eventtyp, data.timestamp);
                        setTimeout(
                          waitForEvents, /* Request next event */
                          1000 /* ..after 1 seconds */                   
                        );
                    },
                error: function (XMLHttpRequest, textStatus, errorThrown){
                    alert("Error:" + textStatus + " (" + errorThrown + ")");
                    setTimeout(
                        'waitForEvents()', /* Try again after.. */
                        "5000"); /* milliseconds (5seconds) */      
                },
            });
        };

        $(document).ready(function(){
                waitForEvents(); /* Start the inital request */
        });
    </script>
</head>
<body>
    <div id="main">
    </div>
</body>
</html>

我的后端 php:

<?php
function getEvents()
{
    $con = mysql_connect("localhost","***","***");
        if(!con)
        {
            die('Could not connect: ' . mysql_error());
        }
        mysql_select_db("arduino_db",$con);

    $result = mysql_query("SELECT * FROM events ORDER BY eventID DESC LIMIT 1");
    if($result)
    {
        $patientroom = $row['rumNr'];
        $patientname = $row['inneboendeNamn'];
        $eventtyp = $row['handelse'];
        $timestamp = $row['timestamp'];
    }

    if($row)
    {
        header('application/json');
                echo json_encode($row);
                exit;
    }

    $lastmodif = isset($_GET['timeStamp']) ? $_GET['timeStamp'] : 0;
    $currentmodif = filemtime($result);

    while($currentmodif <= $lastmodif)
    {
        unsleepp(1000);
        clearstatcache();
        $currentmodif = filemtime($result);
    }
}

?>

我的问题:

  1. 如何从数据库中获取每一行并将每一行以 JSON 格式返回到前端的方法“waitForEvents”。

示例不必是可扩展的、安全的或完整的,它只需要工作=)

更新:基于 Johns 提示的新代码。我得到的只是一个空白页,没有错误。

【问题讨论】:

    标签: php ajax json jquery long-polling


    【解决方案1】:

    我首先想到的是,您的 MySQL 调用有点搞砸了。

    当你运行这一行时:

    $result = mysql_query("SELECT * FROM events ORDER BY eventID DESC LIMIT 1");
    

    您将获得一个 MySQL 资源。你需要利用它来获得你的行:

    $result = mysql_query("SELECT * FROM events ORDER BY eventID DESC LIMIT 1");
    if ($result)
    {
       $row =  mysql_fetch_assoc($result);
       if ($row)
       {
            // Your result is here, as a big associative array.  Each column in your 
            // table is now keyed to this array.  Exact fields will depend on your DB.
            //
            // Just access it like something like this:
    
            $id = $row['id'];
            $time = $row['time_stamp'];
    
       }
    }
    

    将其作为 JSON 回显:

    ... // snip
       if ($row)
       {
            header('application/json');
            echo json_encode($row);
            exit;
       }
    }
    // handle your errors!
    

    补充:在 OP 问题中发现了额外的错误:

    //  The following line isn't valid.  This isn't what you'll get back from $.ajax.
    //    success: function(patientroom, patientname, eventtyp, timestamp) 
    
    //  Corrected code:
    success: function(data, textStatus, jqXHR) 
    /* called when request to getevents.php completes */
    {
        addevents(data.patientroom, data.patientname, data.eventtyp, data.timestamp);
        setTimeout(
          waitForEvents, /* Request next event */
          1000 /* ..after 1 seconds */                   
        );
    },
    

    进一步更新。您混合并匹配了上面的代码。

    $result = mysql_query("SELECT * FROM events ORDER BY eventID DESC LIMIT 1");
    if($result)
    {
       // this has to go inside of this check.  This is where you *ASSIGN* $row.
       $row =  mysql_fetch_assoc($result);
    
       // You need to rekey $row before you output:
       $retVal = array('patientroom'=>$row['rumNr'],
                       'patientname'=>$row['inneboendeNamn'],
                       'eventtyp'=>$row['handelse'],
                       'timestamp'=>$row['timestamp']);
    
       // I'm not sure what you're doing with the incoming timestamp.  Should we just
       // return it back out?
       $retVal['ajax_timestamp'] = $_GET['timeStamp'];
    
       header('application/json');
       echo json_encode($retVal);
       exit; // this exits. Comment this out if you want, but don't try to write anything else out to the buffer.
    }
    
    // Not sure what you're trying to do here.  I'll comment out for now.
    /*
    $lastmodif = isset($_GET['timeStamp']) ? $_GET['timeStamp'] : 0;
    $currentmodif = filemtime($result);
    
    while($currentmodif <= $lastmodif)
    {
        unsleepp(1000);
        clearstatcache();
        $currentmodif = filemtime($result);
    }
    */
    

    }

    【讨论】:

    • 查看我的更新答案。不过……要小心。执行 SELECT * 并将其返回给用户是很危险的。
    • 但这并没有将其发送回方法waitForEvents,而是将其打印出来?
    • 抱歉,您的 AJAX 处理器中也存在错误。我的答案用解决方案进行了修改。
    • 抱歉回复晚了,但我上次发帖时间是 03:35。但请根据您的提示检查更新代码。
    • 嗨,约翰,我尝试了新的更新,但它不起作用。你有没有检查过长轮询的其他步骤。 Maybay 你会更好地理解他们。你自己试过吗?代码,更新?
    【解决方案2】:

    我知道您不应该使用 php 进行长轮询。如果您不是专业的 php-hacker 并且出于许多其他原因,例如:

    • PHP 是为快速执行而设计的(不是为了等待)
    • PHP 将强制您在服务器端进行某种轮询并依赖 sleep()
    • PHP 会吃掉您的 RAM,而每个请求的生成进程也是如此(Apache 会这样做)

    我的项目需要的是在不刷新漏洞站点的情况下显示新数据。我是这样做的:

    <script type="text/javascript">
            var timeoutId;
            var intervalId;
    
            function doIt(){
                $("#main").load("refresh.php");
            }
            $(document).ready(function(){
                timeoutId = setTimeout(function(){
                    doIt();
                    intervalId = setInterval(function(){
                        doIt();
                    }, 5000); //Request the doIt() method every 5ms.
                }, 3000); //Delay calculated on the server to trigger the function at the appropriate time
            }); 
        </script>   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-11
      • 2013-10-01
      • 2016-08-14
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2011-10-20
      相关资源
      最近更新 更多