使用 Php 将数据从一个客户端推送到另一个客户端
Pushing data from one client to another using Php
我正在做关于空气质量监测系统的大学项目,因为数据(比如一些整数值)必须从传感单元获取到网页。
我想要什么
是不是这个urlhttp://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 等。在此先感谢
HTTP 是单向协议。仅从客户端到服务器的请求。是的,绝对需要深入研究 websockets,node.js 等
你想做的事情并没有你想象的那么容易,但这仍然是SSE适合的工作。您不需要使用套接字,也不需要使用 ajax 轮询。
但是您确实需要在服务器上存储一些可以由 PHP 脚本共享的数据库。由于安装 LAMP 堆栈非常简单,我建议使用 MySQL,即使它可能对您的需要来说有点过头了。但是您的数据库可以像文本文件一样简单。
(为了使下面的示例尽可能小,我假设您的数据库为 /tmp/val.txt
,并且我没有进行任何文件锁定或检查错误数据。请注意在不受信任的环境中将其投入生产之前,您需要做一些工作。我建议 pre-creating /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 秒加上网络开销。)如果您需要更低的延迟,请缩短睡眠时间。
您的 front-end 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>
我正在做关于空气质量监测系统的大学项目,因为数据(比如一些整数值)必须从传感单元获取到网页。
我想要什么
是不是这个urlhttp://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 等。在此先感谢
HTTP 是单向协议。仅从客户端到服务器的请求。是的,绝对需要深入研究 websockets,node.js 等
你想做的事情并没有你想象的那么容易,但这仍然是SSE适合的工作。您不需要使用套接字,也不需要使用 ajax 轮询。
但是您确实需要在服务器上存储一些可以由 PHP 脚本共享的数据库。由于安装 LAMP 堆栈非常简单,我建议使用 MySQL,即使它可能对您的需要来说有点过头了。但是您的数据库可以像文本文件一样简单。
(为了使下面的示例尽可能小,我假设您的数据库为 /tmp/val.txt
,并且我没有进行任何文件锁定或检查错误数据。请注意在不受信任的环境中将其投入生产之前,您需要做一些工作。我建议 pre-creating /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 秒加上网络开销。)如果您需要更低的延迟,请缩短睡眠时间。
您的 front-end 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>