title: Why doesn't server-side script stop when EventSource is closed?
body: <p><strong>TL;DR update:</strong> Whether closing an EventSource from the client or closing the client entirely, php continues to execute on the backend and fails to report the correct value for <code>connection_aborted()</code>.  Why might this be?</p>
  
  <p>I have been all over Google and Stack Overflow looking for answers to this, but none of the suggested fixes resolve the issue: I have a simple page testing the functionality of server-sent events using JavaScript and php.  Everything was working well until I realized that server script execution did not stop when a client navigated to another page or refreshed itself.  This appears to be a common problem and the suggestions given in other questions have borne no fruit for me.</p>
  
  <blockquote>
    <p><em>StackOverflow questions I've already investigated</em></p>
    
    <ul>
    <li><p><a href="https://stackoverflow.com/questions/12918650/php-event-source-keeps-executing">PHP Event Source keeps executing</a> (the comments on the accepted answer here almost led to something and then they pulled out to "continue this discussion in chat" and that link is apparently broken)</p></li>
    <li><p><a href="https://stackoverflow.com/questions/50051634/php-server-sent-events-connection-wont-close">PHP Server Sent Events Connection won&#39;t close?</a></p></li>
    <li><p><a href="https://stackoverflow.com/questions/49080653/how-do-i-put-this-on-real-time-i-already-put-async-true-but-it-doesnt-work/49081040#49081040">How do I put this on Real-Time? I already put (async: True) but it doesnt work</a></p></li>
    <li><p><a href="https://stackoverflow.com/questions/6381270/php-connection-aborted-not-working-correctly">PHP connection_aborted() not working correctly</a></p></li>
    <li><p><a href="https://stackoverflow.com/questions/15991113/php-doesnt-detect-connection-abort-at-all">PHP doesn&#39;t detect connection abort at all</a></p></li>
    </ul>
    
    <p><em>Linked articles &amp; other material I've already investigated</em></p>
    
    <ul>
    <li><p><a href="https://www.html5rocks.com/en/tutorials/eventsource/basics/" rel="noreferrer">https://www.html5rocks.com/en/tutorials/eventsource/basics/</a></p></li>
    <li><p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events" rel="noreferrer">https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events</a></p></li>
    </ul>
  </blockquote>
  
  <p>I have stripped the code of everything that I thought could be a possible culprit and I'm still having the issue.  I am especially surprised that <code>connection_aborted</code> continues to report <code>false</code> after the explicit <code>EventSource.close()</code> call in the client or simply closing the client before the 10 second server loop has finished.  Here is my exact code, after stripping out everything but the server-sent event stuff:</p>
  
  <p><em>sse_tests.js</em></p>
  
  <pre><code>document.addEventListener('DOMContentLoaded', () =&gt; {
    // Set up EventSource for receiving server-sent events.
    const testEventSource = new EventSource('sse_tests.php');
    testEventSource.addEventListener('test', (e) =&gt; {
      const data = JSON.parse(e.data);
      console.log(`count: ${data.count}`);
      if (data.count &gt;= 5) {
        testEventSource.close();
      }
    });
  });
  </code></pre>
  
  <p><em>sse_tests.php</em></p>
  
  <pre><code>&lt;?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 &lt;= 10) {
    $eventData = json_encode(array(
      "count" =&gt; $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);
  }
  </code></pre>
  
  <p>The client successfully opens the connection, tracks it for 5 emissions of the <code>test</code> event and then stops seeing any further emissions of the <code>test</code> event, but the server continues to execute for the full count of 10, even after the <code>testEventSource.close()</code> call or a closing of the browser window before the full count of 10, as evidenced by the server log contents here:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>I'm on shared hosting with php 7.2 and minimal tweaks to server configuration.  Let me know if that could be the source of strife, and I'll try to investigate more of the default configurations and share whatever else is needed.</p>