PHP事件源继续执行

Jul*_*ert 3 javascript php html5 server-sent-events

我开始使用JavaScript EventSource对象在HTML5中使用push.我对PHP的工作解决方案非常满意:

$time = 0;
while(true) {
    if(connection_status() != CONNECTION_NORMAL) {
        mysql_close()
        break;
    }
    $result = mysql_query("SELECT `id` FROM `table` WHERE UNIX_TIMESTAMP(`lastUpdate`) > '".$time."'");
    while($row = mysql_fetch_array($result)) {
        echo "data:".$row["id"].PHP_EOL;
        echo PHP_EOL;
        ob_flush();
        flush();
    }
    $time = time();
    sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

但突然间我的WebApp再也无法访问MySQL错误"连接太多".

事实证明,在JavaScript中关闭事件源后,MySQL连接不会关闭:

window.onload = function() {
    sse = new EventSource("push.php");
    sse.onmessage = function(event) {
        console.log(event.data.split(":")[1]);
    }
}
window.onbeforeunload = function() {
    sse.close();
}
Run Code Online (Sandbox Code Playgroud)

所以我猜PHP脚本不会停止执行.die();在客户端连接断开之前有没有办法调用函数(比如)?为什么我的脚本在调用.close();EventSource 后没有终止?!

感谢帮助! -

Eli*_*gem 6

首先:当您将代码包装在一个巨大的while(true)循环中时,您的脚本将永远不会终止.当脚本"用尽代码执行"时,与DB的连接将被关闭,但由于你已经写了一个死锁,所以不会发生这种情况......永远不会发生.
这不是一个EventSource问题,只是做它应该做的事情.老实说,真的,可悲的是你的错.

问题是:用户连接到您的站点,并EventSource实例化该对象.建立与服务器的连接,并请求返回值push.php.您的服务器按照要求执行操作并运行脚本,即-again-只是一个死锁.没有错误,只要php.ini允许它运行,它就可以继续运行.该.close()方法确实取消了输出流(或者更确切地说它应该),但是你的脚本忙于执行无限循环或休眠.假设由于客户端断开连接而停止脚本就像假设任何客户端可能干扰服务器的操作一样.在安全方面,这将是可能发生的最坏情况.现在,回答您的实际问题:导致问题的原因是什么,如何解决?
答案是:HEADERS

看看这个小PHP示例:脚本不是在服务器端保持活动(通过无限循环),而是通过设置正确的标头.

就像一个旁注:请mysql_*尽快抛弃,它被弃用(最后),使用PDO或者mysqli_*说是.老实说,这并不难.

  • 嗯......那不行.我开始使用push时,我正在使用"text/event-stream".当我删除while循环时,Event Source对象返回`on error"函数并关闭连接.当我没有循环时,脚本完成执行并终止.然后关闭流.标题接缝不会打扰它.调用`.close()`仍然不会更改connection_status.无法想象为什么...... (2认同)
  • @EliasVanOotegem,您在链接中引用的示例未通过标题保持活动状态。事实上,它实际上死了,客户端在三秒钟后重新打开连接。 (2认同)