【发布时间】:2020-07-31 02:20:53
【问题描述】:
TL;DR 更新: 无论是从客户端关闭 EventSource 还是完全关闭客户端,php 都会继续在后端执行,并且无法报告 connection_aborted() 的正确值。为什么会这样?
我一直在 Google 和 Stack Overflow 上寻找答案,但没有一个建议的修复程序可以解决这个问题:我有一个简单的页面,使用 JavaScript 和 php 测试服务器发送事件的功能。一切都运行良好,直到我意识到当客户端导航到另一个页面或刷新自身时服务器脚本执行并没有停止。这似乎是一个常见问题,其他问题中给出的建议对我没有任何结果。
我已经调查过的 StackOverflow 问题
PHP Event Source keeps executing(此处接受的答案中的 cmets 几乎导致了一些问题,然后他们退出以“在聊天中继续讨论”,并且该链接显然已损坏)
How do I put this on Real-Time? I already put (async: True) but it doesnt work
我已经调查过的链接文章和其他材料
我已经删除了所有我认为可能是罪魁祸首的代码,但我仍然遇到问题。我特别惊讶connection_aborted 在客户端显式调用EventSource.close() 之后继续报告false,或者只是在10 秒服务器循环完成之前关闭客户端。这是我的确切代码,除了服务器发送的事件之外的所有内容:
sse_tests.js
document.addEventListener('DOMContentLoaded', () => {
// Set up EventSource for receiving server-sent events.
const testEventSource = new EventSource('sse_tests.php');
testEventSource.addEventListener('test', (e) => {
const data = JSON.parse(e.data);
console.log(`count: ${data.count}`);
if (data.count >= 5) {
testEventSource.close();
}
});
});
sse_tests.php
<?php
// Set the event stream header(s).
header("Cache-Control: no-cache");
header("Content-Type: text/event-stream");
// XXX Override automatic detection of client abortion; we'll do it ourselves.
// (This was suggested in another answer, and I have the same issue with or without it)
ignore_user_abort(true);
// Initialize an arbitrary count parameter to investigate client communication.
$count = 1;
while ($count <= 10) {
$eventData = json_encode(array(
"count" => $count,
));
echo "event: test\n";
echo "data: ${eventData}";
echo "\n\n";
ob_flush();
flush();
$aborted = connection_aborted();
error_log("count: ${count}, connection_aborted: ${aborted}");
if ($aborted) {
break;
}
$count++;
sleep(1);
}
客户端成功打开连接,跟踪它 5 次 test 事件的发射,然后停止看到任何进一步的 test 事件发射,但服务器继续执行完整计数 10,即使在之后testEventSource.close() 调用或在完整计数 10 之前关闭浏览器窗口,此处的服务器日志内容证明了这一点:
count: 1, connection_aborted: 0
count: 2, connection_aborted: 0
count: 3, connection_aborted: 0
count: 4, connection_aborted: 0
count: 5, connection_aborted: 0
count: 6, connection_aborted: 0
count: 7, connection_aborted: 0
count: 8, connection_aborted: 0
count: 9, connection_aborted: 0
count: 10, connection_aborted: 0
我正在使用 php 7.2 共享主机,并且对服务器配置进行了最小的调整。如果这可能是冲突的根源,请告诉我,我将尝试调查更多默认配置并分享其他需要的内容。
【问题讨论】:
-
connection_status()的值是多少? -
@miknik 状态为 0(正常)
-
在你的 php.ini 中有这两行吗?
output_buffering = 0 implicit_flush = 1 -
听起来您在某处进行了一些输出缓冲。我刚刚将您的代码复制到了我的服务器上,它运行良好。
-
正确,网页上的控制台日志会以预期的时间间隔更新每个计数。
标签: javascript php server-sent-events eventsource