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

PHP Server Sent Events用无限循环时出现500错误求助

PHP实现Server Side Events(SSE)时无限循环触发500错误问题

问题描述

尝试用PHP实现SSE,按照教程使用无限while循环维持连接,但运行几分钟后就会出现500错误,无法持续发送数据。我的应用必须保持无限循环运行,因为需要通过TCP套接字接收硬件设备的更新,必须维持套接字连接不中断。

仅在使用while循环时会触发错误;移除循环后客户端会每3秒自动重连,不符合业务需求。

环境配置

  • PHP版本:7.3.33
  • 服务器环境:Windows Server 2022/2016 + IIS 10
  • PHP配置:php.ini中output_buffering和zlib.output_compression均设为Off
  • FastCGI配置:PHP的FastCGI Handler中responseBufferLimit设为0

测试代码

sse.php

<?PHP
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(true) {
   $now = date('r');
   echo "data: The time is : {$now}\n\n";
   @ob_flush();
   flush();
   sleep(2);
}
?>

test.html

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
</head>

<body>
    <script>
    var source = new EventSource("sse.php");
    source.onopen = function(e) {
   console.log("The connection to your server has been opened");
}
    source.onmessage = function(e) {
   console.log ("message: " + e.data);
}
    source.onerror = function(e) {
   console.log("The server connection has been closed due to some errors");
}
    </script>
</body>
</html>

PHP错误日志

日志中的错误看起来与当前问题无关:

[17-Nov-2022 21:26:28 UTC] PHP Warning: Module 'mysqli' already loaded in Unknown on line 0
[17-Nov-2022 21:26:28 UTC] PHP Warning: Module 'mbstring' already loaded in Unknown on line 0
[17-Nov-2022 21:26:28 UTC] PHP Deprecated: Directive 'track_errors' is deprecated in Unknown on line 0

已尝试的无效方案

已按照教程修改以下配置,但问题仍未解决:

  • 将php.ini中output_buffering和zlib.output_compression设为Off
  • 将PHP的FastCGI Handler设置中responseBufferLimit设为0

解决方案

针对Windows IIS环境下PHP SSE无限循环触发500错误的问题,需从以下关键配置入手调整:

1. 取消PHP脚本执行时间限制

默认PHP脚本执行时间限制为30秒,无限循环会触发超时导致500错误。可通过两种方式修改:

  • 编辑php.ini:
    max_execution_time = 0
    
  • 在sse.php开头添加代码:
    ini_set('max_execution_time', 0);
    

注意:CLI模式下max_execution_time默认是0,但FastCGI模式需显式设置。

2. 调整IIS FastCGI超时设置

IIS的FastCGI进程有自身超时机制,即使PHP超时设为0,进程仍可能被回收:

  1. 打开IIS管理器,找到FastCGI设置
  2. 找到对应PHP处理程序,双击进入编辑界面
  3. 将活动超时和请求超时修改为较大值(如86400秒,即24小时),或根据业务需求调整

3. 禁用IIS输出缓存

即使PHP关闭了输出缓冲,IIS自身可能仍会缓冲text/event-stream类型的输出:

  1. 在IIS管理器中找到目标网站,打开输出缓存
  2. 点击添加,选择text/event-stream MIME类型,取消勾选“启用缓存”
  3. 检查网站HTTP响应标头,确保无强制缓存的配置

4. 优化脚本连接检测

在循环中添加客户端断开检测,避免无效占用资源,同时移除错误抑制以便排查缓冲问题:

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

// 禁用脚本超时
ini_set('max_execution_time', 0);

while(true) {
   // 检测客户端是否断开连接
   if (connection_aborted()) {
       exit();
   }

   $now = date('r');
   echo "data: The time is : {$now}\n\n";
   ob_flush();
   flush();
   sleep(2);
}
?>

5. 调整IIS应用程序池回收设置

IIS应用程序池默认定期回收进程,会直接中断SSE连接:

  1. 打开应用程序池的高级设置
  2. 调整回收参数:禁用“固定时间间隔”回收,或根据业务需求延长回收周期
  3. 将闲置超时设为0,避免闲置时回收进程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:35:25