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

问题描述 投票:1回答:1

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

我一直在Google和Stack Overflow上寻找解决方案,但是没有建议的解决方案可以解决此问题:我有一个简单的页面,使用JavaScript和php测试服务器发送事件的功能。一切运行良好,直到我意识到当客户端导航到另一个页面或刷新自身时,服务器脚本执行不会停止。这似乎是一个普遍的问题,其他问题中的建议对我没有任何帮助。

我已经调查过的StackOverflow问题

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共享托管,并且对服务器配置进行了最小的调整。让我知道这是否可能是冲突的根源,我将尝试研究更多默认配置并共享其他所需的东西。

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

javascript php server-sent-events eventsource
1个回答
0
投票

根据最新信息,我相信这肯定是错误的:

ignore_user_abort(true);
© www.soinside.com 2019 - 2024. All rights reserved.