gpt4 book ai didi

javascript - 为什么 EventSource 关闭时服务器端脚本不停止?

转载 作者:行者123 更新时间:2023-12-01 17:17:40 30 4
gpt4 key购买 nike

TL;DR 更新:无论是从客户端关闭 EventSource 还是完全关闭客户端,php 都会继续在后端执行并且无法报告 connection_aborted() 的正确值.为什么会这样?

我一直在 Google 和 Stack Overflow 上寻找答案,但没有一个建议的修复程序可以解决这个问题:我有一个简单的页面,使用 JavaScript 和 php 测试服务器发送事件的功能。一切都运行良好,直到我意识到当客户端导航到另一个页面或刷新自身时服务器脚本执行并没有停止。这似乎是一个常见问题,其他问题中给出的建议对我没有任何结果。

StackOverflow questions I've already investigated

Linked articles & other material I've already investigated



我已经删除了我认为可能是罪魁祸首的所有代码,但我仍然遇到问题。我特别惊讶 connection_aborted继续报道 false在显式 EventSource.close() 之后在 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);
}

客户端成功打开连接,跟踪 test 的 5 次发射。事件,然后停止看到 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 共享主机,并且对服务器配置进行了最小的调整。让我知道这是否可能是冲突的根源,我将尝试调查更多默认配置并分享其他需要的内容。

最佳答案

根据更新的信息,我相信这绝对是错误的:

ignore_user_abort(true);

这应该是:
ignore_user_abort(false);

...这样断开连接就不会被忽略。之后发生的事情是个谜。 MDN 报告说连接是持久的,因此可能是浏览器中的一个错误没有关闭连接。如果存在负载平衡器或反向代理,则可能是它们的问题。这可能是 Web 服务器中的问题。或者它可能是 PHP 配置中的问题。

在聊天中,看起来测试服务器很可能是在 FastCGI 下运行 PHP 的 nginx。你是用 Apache 和 mod_php 代替吗?如果是这样,当您将 PHP 作为 CGI 运行时还会发生这种情况吗?这应该有助于进一步隔离问题。

我也会使用 connection_status() 以便您可以更加确定连接状态。 https://www.php.net/manual/en/features.connection-handling.php

关于javascript - 为什么 EventSource 关闭时服务器端脚本不停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61274048/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com