我正在更新一個呈現實時傳感器數據的Web應用程序,它在當前的第一次迭代中是通過連續的AJAX輪詢實現的。 但是,爲了讓這更像是一個'真正的實時'應用程序,我希望它是基於事件的。實時傳感器數據作爲從Python到PHP的服務器發送事件(SSE)?
我一直在閱讀基於事件的技術,並且基於實時通信只需要一種方式(服務器 - >客戶端)的事實,我選擇使用Server-Sent Events (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,但經過一些研究後,它確實看起來是一個很好的解決方案。然而,根據文檔,不應該是超時工作而是'blpop'而不是'lpop'? (https://redis.io/commands/blpop)。另外,你可以解釋HTTP_LAST_EVENT_ID部分是如何工作的嗎? 'echo'重試的功能是什麼:2000 \ n「;'? –
感謝您指出和是blpop(固定)。如果您閱讀SSE的詳細信息,如果瀏覽器斷開連接並自動重新連接,它將通過HTTP_LAST_EVENT_ID通過頭和php發送最後一個事件ID,這允許服務器端發送斷開連接期間可用的數據。 「retry:2000 \ n」告訴瀏覽器在2000毫秒後自動重新連接(保持網絡穩定,避免斷開總是比快速重新連接好) –
對最後一個事件ID有意義,謝謝!重試功能是否需要任何附加代碼,或者是否使用EventSource接口調用? –