【问题标题】:Server Side Events with PHP & MySQL使用 PHP 和 MySQL 的服务器端事件
【发布时间】:2018-01-16 00:22:06
【问题描述】:

我正在使用 PHP 和 MySQL 构建一个(非常基本的)应用程序。此应用程序的目的是在网页上显示“实时”数据交易。这些事务来自 MySQL 数据库中的 transactions 表。

到目前为止,我可以在网页上检索和显示数据。但是,当新事务插入transactions 表时,我希望看到数据刷新

当前实时提要重复显示最后一条记录,直到插入新事务,此循环。

到目前为止我的代码是;

transactions.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>HTML5 Server-Sent Events</title>
    <script type="text/javascript">
        window.onload = function(){
            var source = new EventSource("transactions.php");
            source.onmessage = function(event){
                document.getElementById("result").innerHTML += "New transaction: " + event.data + "<br>";
            };
        };
    </script>
</head>
<body>
    <div id="result">
        <!--Server response will be inserted here-->
    </div>
</body>
</html>

transactions.php

<?php 
include 'conn.php'; // database connection

header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");

$query = "SELECT TimeStamp, CardNo FROM transactions ORDER BY TimeStamp DESC LIMIT 1";
// `TimeStamp` is in the format YYYY-MM-DD H:i:s 
if ($result = $conn->query($query)) {
    $row = $result->fetch_assoc();
    echo "data: " . $row['CardNo'] . "\n\n";
}
flush();
?>

如果这有什么不同的话,我一直在关注this tutorial

我的问题;

  • 如何仅在插入新交易时刷新实时供稿
  • 当前实时提要大约每 3 秒刷新一次,这是在哪里设置的?

感谢任何帮助。

【问题讨论】:

  • 您的查询看起来会从事务表中获取所有行。但是你每次只从结果集中取一行??????这很可能总是同一行,但不一定是第一个或最后一个进入表格的行
  • 基于这段代码,您可能必须在每次检索值时存储最新的 id,并检查 id 是否
  • 你的服务器 PHP 代码应该在一个循环中。循环应该以某种方式检查新条目,并且只有在找到新条目时才发送它。服务器通过不断循环提供消息泵。 javascript 只是对来自服务器 PHP 代码的传入消息做出反应
  • 不要认为这是一个很好的教程。把它从你的好教程列表中删除
  • @marekful 的回答非常好。这应该就是让您的泵正常工作所需要的一切

标签: javascript php mysql html


【解决方案1】:

您在服务器端缺少一些东西来完成这项工作。

首先,正如@RiggsFilly 指出的那样,您需要在语句中使用 WHERE 子句。条件应该是寻找比上次发送更新的交易。

为此,您需要跟踪上次发送消息的时间戳。

只有当现在带有条件的查询返回结果时,服务器才应该发送消息。

最后,检查新交易并在发现时发送消息的整个例程必须保持在一个循环中。

<?php 
include 'conn.php'; // database connection

header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");

$query = "SELECT TimeStamp, CardNo FROM transactions WHERE TimeStamp > ?";
$stmt = $conn->prepare($query);
$ts = time();

while(true) 
{
    if ($result = $stmt->execute([$ts])) {
        $row = $result->fetch_assoc();
        echo "data: " . $row['CardNo'] . "\n\n";
        $ts = $row['TimeStamp'];
        flush();
    }
    sleep(2);
}

【讨论】:

  • 是的,更像是这样
  • 感谢@marekful 的详细回答,我很感激。但是当我使用您提供的代码时,我在屏幕上看不到任何数据,只是一个白页。你对我如何解决这个问题有什么建议吗?我数据库中的TimeStamp 格式为YYYY-MM-DD H:i:s,如果这有什么不同?
  • 另外,查询中的占位符? 不需要bind 吗?谢谢
  • 很好,非常感谢。垃圾呢? php 中的脚本同时连接是否存在?关闭网站后呢?
【解决方案2】:
  1. 如何仅在插入新交易时刷新实时提要?

    这个问题我不清楚。

    transactions.php 总是返回交易表的最后一条记录。

    如果您想显示交易表中新插入的记录,您必须在脚本中添加验证,无论是客户端还是服务器端

    这是检查事务表是否已修改的查询?

    SELECT update_time FROM information_schema.tables WHERE  table_schema='mydb' AND table_name='mytable' and update_time = 'your validation time';
    
  2. 实时提要目前大约每 3 秒刷新一次,这是在哪里设置的?

    通常,当连接关闭时,浏览器会自动重新连接到事件源,但该行为可以从客户端或服务器中取消。 要取消来自客户端的流,只需调用:source.close();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2013-05-01
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多