【问题标题】:Pushing data from one client to another using Php使用 Php 将数据从一个客户端推送到另一个客户端
【发布时间】:2017-02-20 17:46:31
【问题描述】:

我正在制作关于空气质量监测系统的大学项目,其中数据(比如一些整数值)必须从传感单元获取到网页。

我想要什么

这个 url http://localhost/AQProject/recordupdate.php?val=2 调用的脚本是否更新了显示内容的网页。现在我知道我可以将该数据保存在数据库中并每两秒运行一次基于 ajax 的查询以检查更新,但我希望该更新由服务器推送。

我做了什么:

我试过Server sent events。这是我尝试过的

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

if($_SERVER["REQUEST_METHOD"]=="GET")
{
    if(empty($_GET["val"])) die ("Empty Value from source");
    else
    {
        $v = $_GET['val'];
        echo "data: The Pollution stub value is {$v}".PHP_EOL;
        ob_flush();
        flush();
    }
}?>

而且html有脚本

    <script>
if(typeof(EventSource) !== "undefined") {
    var source = new EventSource("recordupdate.php");
    source.onmessage = function(event) {
        document.getElementById("result").innerHTML = event.data + 
        "<br>";
    };
} else {
    document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>

现在,我已经弄清楚了(如果我错了,请纠正我)它不会起作用,因为当另一个客户端(传感单元)调用 recordupdate.php 时,它的脚本实例与网页调用的脚本实例不同客户。

有没有可能使用server sent events 做到这一点的方法?或者我绝对需要深入研究 websockets、node.js 等。在此先感谢

【问题讨论】:

    标签: javascript php node.js websocket server-sent-events


    【解决方案1】:

    您想做的事情并不像您希望的那么容易,但这仍然是 SSE 适合的工作。不需要使用套接字,也不需要使用 ajax 轮询。

    但是您确实需要一些数据库存储,在服务器上,可以由 PHP 脚本共享。由于安装 LAMP 堆栈非常简单,因此我建议使用 MySQL,即使它对于您的需要可能有点过分。但是您的数据库可以像文本文件一样简单。

    (为了使以下示例尽可能小,我假设您的数据库将是/tmp/val.txt,并且我没有进行任何文件锁定或检查错误数据。请注意,您需要这样做在将其投入生产之前,在不受信任的环境中进行一些工作。我建议预先创建 /tmp/val.txt 以避免任何关于文件不存在的噪音。)

    您的 recordupdate.php 有责任记录给定的值:

    <?php
    if($_SERVER["REQUEST_METHOD"]=="GET")
    {
       if(empty($_GET["val"])) die ("Empty Value from source");
       else file_put_contents("/tmp/val.txt", $_GET['val']);
    }
    

    然后你有 sse.php,web 客户端连接到:

    <?php
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    $prev = '';
    while(1){
      $v = file_get_contents("/tmp/val.txt");
      if($v != $prev){
        echo "data: The Pollution stub value is {$v}\n\n";
        $prev = $v;
        }
      usleep(100000);  //0.1s
      }
    

    此脚本每秒检查 10 次文本文件是否有更改。一旦它发现一个,它就会将它发送给客户端。 (平均延迟为 0.05 秒加上网络开销。)如果您需要更低的延迟,请缩短睡眠时间。

    对前端 HTML 的唯一更改是调用“sse.php”:

    <script>
    if(typeof(EventSource) !== "undefined") {
        var source = new EventSource("sse.php");
        source.onmessage = function(event) {
            document.getElementById("result").innerHTML = event.data + 
            "<br>";
        };
    } else {
        document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
    }
    </script>
    

    【讨论】:

      【解决方案2】:

      HTTP 是一种单向协议。仅从客户端到服务器的请求。是的,绝对需要深入研究 websockets、node.js 等。

      【讨论】:

      • 但是请看,数据确实会从一个客户端流向另一个客户端,没有双工连接。它必须比打开全双工连接更简单。
      • 浏览器只能通过 HTTP 发送请求和接收应答。不再。有关示例,请参见 habrahabr.ru/post/209864 。有简单的php服务器和js客户端示例。
      猜你喜欢
      • 2015-09-04
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 2011-05-20
      • 2015-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多