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

Javascript EventSource持续重连PHP SSE端点问题咨询

SSE(Server-Sent Events)无限重连问题解析

问题描述

尝试用PHP和SSE实现简单Demo时,发现页面会无限次重连后端端点,而非仅调用一次。

PHP代码(sse.make-segment-snapshots.php)

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

for ($i = 0; $i <= 5; $i++) {
    $time = date('r');
    echo "data: The server time is: {$time}\n\n";
    flush();
}

echo "data: END-OF-STREAM" . "\n\n";
flush();

JS/jQuery代码

$('.btn-snap-all').on('click', function () {
      const source = new EventSource('sse.make-segment-snapshots.php');
      const listener = function (event) {
           if(typeof event.data !== 'undefined'){
                console.log(event.data);
           }
      };
      source.addEventListener('open', listener, false);
      source.addEventListener('message', listener, false);
      source.addEventListener('error', listener, false);

      return false;
});

原因分析

这是预期行为,但和你对SSE的设计逻辑理解有偏差:

  • EventSource的核心机制是:一旦后端连接关闭,它会自动尝试重新建立连接(默认重连间隔为3秒)。
  • 你的PHP脚本执行完循环和最后一条消息后,会自动终止进程、关闭HTTP连接,前端的EventSource检测到连接断开后,就会触发内置的重连机制,导致无限循环请求。

解决方法

根据你的业务需求,有两种常见处理方式:

1. 后端保持长连接(持续推送场景)

如果需要持续推送数据,PHP脚本要保持运行不终止,可通过循环+sleep实现,注意提前禁用脚本超时:

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// 禁用脚本执行超时限制
set_time_limit(0);

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

$i = 0;
while ($i <= 5) {
    $time = date('r');
    echo "data: The server time is: {$time}\n\n";
    flush();
    // 每秒推送一次数据
    sleep(1);
    $i++;
}

echo "data: END-OF-STREAM\n\n";
flush();

2. 客户端收到结束信号后主动关闭连接(一次性推送场景)

如果只是一次性推送完数据就结束,在前端收到END-OF-STREAM消息时,调用source.close()关闭EventSource,阻止自动重连:

$('.btn-snap-all').on('click', function () {
      const source = new EventSource('sse.make-segment-snapshots.php');
      const listener = function (event) {
           if(typeof event.data !== 'undefined'){
                console.log(event.data);
                // 检测到结束信号,主动关闭连接
                if (event.data === 'END-OF-STREAM') {
                    source.close();
                }
           }
      };
      source.addEventListener('open', listener, false);
      source.addEventListener('message', listener, false);
      source.addEventListener('error', listener, false);

      return false;
});

额外提示

  • 后端推送消息时,必须确保每个data:字段后都带有两个换行符(\n\n),这是SSE的强制格式要求,否则前端可能无法正确解析消息。
  • 若后端因超时、错误等异常情况关闭连接,EventSource同样会触发重连,可在error事件中添加异常处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:10:31