duanou9758 2017-06-05 02:35
浏览 396
已采纳

实时传感器数据作为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!

  • 写回答

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();
        }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#java#的问题,请各位专家解答!
  • ¥15 急matlab编程仿真二阶震荡系统
  • ¥20 TEC-9的数据通路实验
  • ¥15 ue5 .3之前好好的现在只要是激活关卡就会崩溃
  • ¥50 MATLAB实现圆柱体容器内球形颗粒堆积
  • ¥15 python如何将动态的多个子列表,拼接后进行集合的交集
  • ¥20 vitis-ai量化基于pytorch框架下的yolov5模型
  • ¥15 如何实现H5在QQ平台上的二次分享卡片效果?
  • ¥30 求解达问题(有红包)
  • ¥15 请解包一个pak文件