You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Server-Sent Events连接无法关闭?技术求助

Fixing Unclosable Server-Sent Events (SSE) Connection with EventSource

Let's break down why your SSE connection might be refusing to close, and walk through actionable fixes tailored to your code.

First: Fix a Critical JS Bug in Your Event Binding

Looking at your JavaScript code, you're assigning onmessage to the EventSource constructor instead of your actual myEventSource instance. This is a common mistake that breaks both event handling and your ability to reference the connection later to close it.

Here's the corrected JS code:

var myEventSource; 
if (typeof(EventSource) !== "undefined" && !myJsIssetFunction(viridem.serverSideEvent.config.reindexProcessingEvent)) { 
  myEventSource = new EventSource('/my/url/path.php?event=myevent'); 
  // Bind to the INSTANCE, not the EventSource constructor
  myEventSource.onmessage = function(e) { 
    // Handle your e.data here
    console.log('Received SSE data:', e.data);
  };

  // Add error handling to catch connection issues
  myEventSource.onerror = function(error) {
    console.error('SSE connection error:', error);
    // Auto-close on critical errors
    this.close();
  };
}

// Create a dedicated function to close the connection
function closeSSEConnection() {
  // Only close if the connection exists and is open
  if (myEventSource && myEventSource.readyState !== EventSource.CLOSED) {
    myEventSource.close();
    myEventSource = null; // Clear the reference to aid garbage collection
    console.log('SSE connection successfully closed');
  }
}

Call closeSSEConnection() whenever you need to terminate the connection (e.g., a button click, after a task completes, or when navigating away from the page).

Second: Ensure Your PHP Backend Properly Terminates the Connection

If your PHP script doesn't exit cleanly or fails to send proper signals, the connection might hang open. Here's how to optimize your PHP code:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');

$event = $_GET['event'] ?? '';
if ($event === 'myevent') {
  // Your existing logic to send data
  echo "data: Processing update...\n\n";
  flush();
  ob_flush();

  // When you want to close the connection from the server:
  $taskCompleted = false; // Replace with your actual completion check
  if ($taskCompleted) {
    // Send a custom "close" event to notify the frontend
    echo "event: close\n";
    echo "data: Server closing connection\n\n";
    flush();
    ob_flush();
    // Exit immediately to terminate the connection
    exit();
  }
}
?>

Then, add a listener in your JS to catch this server-initiated close signal:

myEventSource.addEventListener('close', function(e) {
  closeSSEConnection();
});

Common Pitfalls to Avoid

  • Don't rely on browser auto-close: Browsers might not immediately close SSE connections when navigating away, so always explicitly call close().
  • Prevent cached connections: Add a unique timestamp to your SSE URL (e.g., '/my/url/path.php?event=myevent&t=' + Date.now()) to avoid stale connections from browser caching.
  • Check readyState: Before calling close(), verify the connection is in the OPEN state (myEventSource.readyState === EventSource.OPEN).

内容的提问来源于stack exchange,提问作者Jordan Daigle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:53:57