我能否检测客户端何时与 CGI 断开连接?

我能否检测客户端何时与 CGI 断开连接?

我有一个资源密集型的 CGI,需要很长时间才能开始发送数据。我们见过不少这样的情况:不耐烦的人会重新加载几次,然后触发 CGI 的额外加载运行,或者客户端超时并断开连接,但 CGI 仍在运行。

有什么好方法可以检测这种情况何时发生?它甚至不需要在 CGI 本身内(如果不是,可能会更好——它会交给我无法控制的另一个程序),但可以是一个 cron 作业,它会不时运行以查找要收集的死连接。

我目前正在使用 Apache,但是这个问题太大了,如果它有处理它的条款(或者有办法让我监控该问题),我愿意运行其他 Web 服务器。

答案1

通常,您无法检测到断开的连接,直到您开始向用户写回。否则,您的进程将继续执行其工作,而不会注意到用户端的连接中止。这个帖子就算是讲PHP也是相关的,概念应该是一样的。

您可以尝试以下方法:

  1. 在后台执行耗时的工作。当用户请求 CGI 时,不要将该任务作为正常的阻塞调用来执行。只需向用户返回任何内容以告知该请求正在处理中。当然,您需要找到某种方法来更新视图或提供另一个页面以使用某些请求 ID 或 IP 检查作业状态。
  2. 尽快将数据发回客户端,如果发送失败(表示连接断开),则退出。例如,您可以每隔几秒或几分钟发送一次作业进度。

如果您将当前正在运行的作业保存在数据库中,则可以保存请求 ID 和/或客户端 IP 地址。因此,您可以检测并忽略对同一资源的重复请求,并告知用户“您的请求正在处理中”。

答案2

警告:此信息可能已过时。请参阅最后一段。

我记得我遇到过同样的问题,并且用硝化甘油(无解析标头)CGI 脚本。

通常,apache 会从您的脚本中收集所有标头,并在读取完标头后,使用您未提供的一些标准标头对其进行修改。这也意味着,只要您没有完成标头,apache 就不会向客户端发送任何内容。

使用 nph 脚本,您必须提供所有标头,但 apache 会立即将它们发送给客户端,并在客户端断开连接后向您的 CGI 脚本发送 SIGPIPE。因此,您可以X-Slowly-Counting-Part-nnn: yes每隔几秒发送一些标头,以防止客户端超时,并且如果客户端断开连接,您会收到通知。

这仍然存在问题,你必须先发送 HTTP 状态,但如果你发送“Content-Length:0”或“Content-Length:1”并关闭连接而不发送任何内容,你的文件下载器应该假设网络错误并采取相应行动。

您可能必须通过您的进程来传输其他程序的输出,但至少如果您在 Linux 上使用系统调用,这不会对性能造成重大影响sendfile(2)

所有这些的问题在于我至少在 10 年前就使用过它,可能是在 Apache 1.3 上,而谷歌搜索apache cgi nph没有找到任何有用的信息。所以也许 nph 功能在此期间被删除了 - 但也许没有,我承认我没有仔细查看。

答案3

老问题了,但我遇到了同样的问题并解决了检查连接是否稳定的问题:

就我而言,我在服务器上运行一个 bash 脚本。环境变量由 mod_cgi 导出,我相信此解决方案适用于在 CGI 上运行的任何程序/脚本

ss -nt state established "( sport = :$SERVER_PORT and dport = $REMOTE_ADDR:$REMOTE_PORT )" 2>/dev/null | grep -q "$REMOTE_ADDR:$REMOTE_PORT"
if [ "$?" -ne '0' ]; then
     # Client closed browser/connection
fi

相关内容