duanou9758
2017-06-05 02:35
浏览 345

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

I'm in the process of updating a web app presenting real-time sensor data, which in it's current first iteration does this by continuous AJAX polling. However, in order to make this more like a 'true real-time' app, I would like it to be event-based.

I've been reading up on event-based techniques, and based on the fact that the real-time communication only has to go one way (server - > client), I have chosen to go with Server-Sent Events (SSE) for now instead of something like websockets. As described here on the Mozilla Docs, this is easily implemented on the server side with something like (a little simplified):

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

");

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

   sleep($short_time_to_spare_cpu);
}
?>

and on the client side with:

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

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

All the above works fine for me. However, the sensor data is initially retrieved by a Python script running continuously on the server, so how do I transfer the sensor data from the Python script to the PHP script IMMEDIATELY when it is retrieved, so that an event can be generated and sent?

Can I do something like depicted below? : scenario1

At the same time all new data is stored in a MySQL db, so I could of course make the PHP script query the db really often for new entries, but there has to be a smarter way. So can I make 2.1 and 2.2 in the image happen at the same time?

All the answers I could find in here describes how data can be transferred by making the PHP execute the Python script, but that is not what I want as this has to run whether or not a user asks for data.

Is a kind of socket the way to go, and if so, can you point me in the direction of how to do so? I hope you can help me out!

图片转代码服务由CSDN问答提供 功能建议

我正在更新呈现实时传感器数据的Web应用程序,这是当前的第一次迭代 通过连续的AJAX轮询来做到这一点。 但是,为了使它更像“真正的实时”应用程序,我希望它是基于事件的。

我一直在阅读基于事件的技术,并且基于实时通信只需要一种方式(服务器 - &gt;客户端)的事实,我有 现在选择使用服务器发送事件(SSE)而不是像websockets这样的东西。 <此处有关Mozilla文档的描述,这很容易在服务器端实现,例如(稍微简化):

 &lt;?php 
 // SSEscript.php 
date_default_timezone_set(“America  / New_York“); 
header(”Content-Type:text / event-stream 
 
“); 
 
而(1){
 if($ new_data_available){
 echo”data:“。  $ data; 
} 
 
 sleep($ short_time_to_spare_cpu); 
} 
?&gt; 
   
 
 

在客户端使用:

 &lt; script&gt; 
var evtSource = new EventSource(“SSEscript.php”); 
 
evtSource.onmessage = function(e){
 var data = e.data  ; 
 //对数据对象执行某些操作
} 
&lt; / script&gt; 
   
 
 

以上所有操作都适合我。 但是,传感器数据最初是由在服务器上连续运行的Python脚本检索的,因此在检索传感器数据时如何将传感器数据从Python脚本立即传输到PHP脚本,以便生成并发送事件 ?

我可以做下面描述的事情吗? :

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

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

是一种插座方式,如果是这样,你能指点我这样做的方向吗? 我希望你能帮助我!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douyu7618 2017-06-05 02:46
    已采纳

    I use redis to do the signalling between python and redis. After python do all the stuffs, rpush a token (or the latest data) into a redis queue. In the PHP I use a while(true) loop to hold the request and redis lpop(queue,timeout) to wait for the token, and send data out, something like this:

    <?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
    ";
    
        $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
    ";
            echo "data: $data
    
    ";
            ob_flush();
            flush();
        }
    
    点赞 打赏 评论

相关推荐 更多相似问题