使用Php

时间:2017-02-19 18:51:14

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

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

我想要什么

此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等。提前感谢

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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,网络客户端连接到:

<?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>