开发者问题收集

使用无限循环时 PHP 服务器发送事件错误 500

2022-11-17
810

因此,我在使用 PHP 时遇到服务器端事件问题。我尝试了网上各种不同的教程,这些教程都利用了无限的 while 循环,但几分钟后,我所有的尝试都以 500 错误告终,而不是发送数据。

对于我的应用程序,我需要脚本继续无限循环运行,因为我通过 TCP 套接字从硬件设备获取更新,并且为了让设备向我发送更新,我必须保持套接字连接打开。

我的设置如下:
PHP 版本 7.3.33
带有 IIS 10 的 Windows Server 2022(也尝试在带有 IIS 10 的 Windows Server 2016 上)
output_buffering 和 zlib.output_compression 都设置为“Off”
在 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>

理论上,这应该每 2 秒向客户端发送一个带有当前时间的数据字符串,但实际上却出现了 500 错误。我必须补充一点,只有在实现 while 循环时才会出现这种情况。如果我删除 while 循环,那么它可以与客户端每 3 秒重新连接一次的情况一起工作(这对我的应用程序不起作用)。

除非有人提出其他建议,否则 PHP 日志仅显示以下错误,这些错误似乎与我的问题无关:
[2022 年 11 月 17 日 21:26:28 UTC] PHP 警告:模块“mysqli”已加载到未知的第 0 行
[2022 年 11 月 17 日 21:26:28 UTC] PHP 警告:模块“mbstring”已加载到未知的第 0 行
[2022 年 11 月 17 日 21:26:28 UTC] PHP 已弃用:指令“track_errors”已在未知的第 0 行中弃用

我已经搜索了好几天的解决方案,但到目前为止没有任何效果。有谁对 IIS/PHP 设置中需要更改的潜在设置有任何建议,以使其正常工作?

一些教程建议进行以下配置更改: php.ini > output_buffering 和 zlib.output_compression 设置为“Off” 在 PHP 的 FastCGI Handler 设置中,responseBufferLimit 设置为 0。

但这些都对脚本没有任何影响。

2个回答

HTTP 500 错误是服务器错误。它通常是由于使用超出 PHP 内存限制或超出 PHP 超时限制的无限循环而导致的。它可能会导致 500 错误,并且不会写入日志。

您可以通过 PHP 增加内存限制。这将设置允许脚本分配的最大内存量(以字节为单位)。有关“memory_limit”的更多信息,您可以参考

TengFeiXie
2022-11-18

经过多次反复尝试后,我终于解决了这个问题。如果其他人有类似的问题,以下是我采取的步骤。

  1. 似乎 PHP 在我的 IIS 安装中被引用了 2 次(第二次就像 Fast-CGI 一样,这是我第一次错过它的原因,所以我不得不在两个处理程序中添加“responseBufferLimit = 0”。这使无限循环能够工作而不会出现 500 错误。

  2. 在 IIS 中的服务器配置页面上,有一些 FastCGISettings 选项。其中有一个“请求超时”设置。默认情况下,它设置为 90 秒。我将其设置为 600 秒(或 10 分钟),现在我获得了 10 分钟的恒定数据流,然后脚本超时并重新启动。您只能选择 10 到 2592000 秒之间的值,但 10 分钟对我的应用程序来说应该足够了。

非常感谢所有提供建议!

forde52
2022-11-21