javascript - 使用 Php 将数据从一个客户端推送到另一个客户端

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

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

我想要什么

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

我做了什么:

我已经尝试过服务器发送事件。这是我尝试过的

<?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 时,它是一个不同的实例该脚本与网页客户端调用的脚本不同。

有没有可能使用服务器发送事件来做到这一点?或者我绝对需要深入研究 websockets、node.js 等。提前致谢

最佳答案

你想做的事情并不像你希望的那么容易,但这仍然是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 秒加上网络开销。)如果需要更低的延迟,请缩短 sleep 时间。

对前端 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>

关于javascript - 使用 Php 将数据从一个客户端推送到另一个客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42331373/

相关文章:

javascript - 如何修复 "Uncaught PDOException: ...Conversion failed when converting date and/or time from character string"?

bash - 如何在bash命令行上输出文件列表

node.js - 如何快速执行终端命令?

javascript - 在 Angular 中使用 ng-click 嵌套 div

javascript - 如何从外部文件onload正确执行函数?

javascript - 使用 native react 发送电子邮件(带附件,android)

javascript - 如何水平对齐 flex 盒中的一项?

php - 获取在 PHP 中创建对象的行和文件

javascript - html download 属性重定向到 url 而不是下载

javascript - 当python仍在运行时在node.js上显示python数据