从 Python 到 PHP 的实时传感器数据作为服务器发送事件 (SSE)?

Real-time sensor data as Server-Sent Events (SSE) from Python through PHP?

我正在更新一个呈现实时传感器数据的网络应用程序,在当前的第一次迭代中,它通过连续 AJAX 轮询来实现。 但是,为了使它更像一个 'true real-time' 应用程序,我希望它是基于事件的。

我一直在阅读基于事件的技术,基于实时通信只能采用一种方式(服务器 - > 客户端)这一事实,我选择了 Server-Sent现在使用事件 (SSE) 而不是像 websockets 这样的东西。 如 here on the Mozilla Docs 所述,这很容易在服务器端实现(稍微简化):

<?php
// SSEscript.php
date_default_timezone_set("America/New_York");
header("Content-Type: text/event-stream\n\n");

while (1) {
   if ($new_data_available) {
      echo "data:". $data;
   } 

   sleep($short_time_to_spare_cpu);
}
?>

并在客户端:

<script>
var evtSource = new EventSource("SSEscript.php");

evtSource.onmessage = function(e) {
   var data = e.data;
   // Do something with data object
} 
</script>

以上所有对我来说都很好。 但是,传感器数据最初是由 Python 脚本 运行 在服务器上连续检索的,因此如何将传感器数据从 Python 脚本传输到 PHP检索时立即编写脚本,以便生成和发送事件?

我可以做如下所示的事情吗? :

同时所有新数据都存储在 MySQL 数据库中,所以我当然可以让 PHP 脚本经常查询数据库以获取新条目,但必须有更聪明的方法。那么我可以让图像中的2.1和2.2同时发生吗?

我在这里找到的所有答案都描述了如何通过使 PHP 执行 Python 脚本来传输数据,但这不是我想要的,因为这必须 运行 用户是否请求数据。

是一种套接字方式吗?如果是的话,你能指出我如何做的方向吗? 我希望你能帮助我!

我使用redis 在python 和redis 之间进行信号传输。 python 完成所有操作后,将令牌(或最新数据)推送到 redis 队列中。在 PHP 中,我使用 while(true) 循环来保存请求,并使用 redis lpop(queue,timeout) 等待令牌,并发送数据,如下所示:

<?php
    require __DIR__.'/predis-1.0/autoload.php';
    header("Content-Type: text/event-stream");
    header("Cache-Control: no-cache");
    header("Connection: keep-alive");

    $lastId = isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? 
              $_SERVER["HTTP_LAST_EVENT_ID"] : null;
    if (isset($lastId) && !empty($lastId) && is_numeric($lastId)) {
        $lastId = intval($lastId);
        $lastId++;
    }

    $index = isset($_GET['index']) ? $_GET['index'] : null;

    echo "retry: 2000\n";

    $client = new Predis\Client();
    while (true) {
        $data = $client->blpop('queue',5);
        if ($data) {
            error_log("$index : " . strlen($data));
            sendMessage($lastId, $data);
            $lastId++;
        }
    }

    function sendMessage($id, $data) {
        echo "id: $id\n";
        echo "data: $data\n\n";
        ob_flush();
        flush();
    }