【问题标题】:Interrupted server-side perl CGI script when client-side browser closes客户端浏览器关闭时中断的服务器端 perl CGI 脚本
【发布时间】:2010-08-09 13:59:03
【问题描述】:

我一直在尝试解决一个小问题,但似乎我无法解决。

我编写了一个 HTML 页面,它在提交表单时调用 perl CGI 脚本。这个 CGI 在服务器端执行一定数量的任务,我让脚本将这些任务的步骤打印到 HTML 页面上的 iframe 中。问题是,如果客户端关闭他的浏览器或刚刚离开页面,CGI 脚本会在服务器端中断

HTML 代码:

<form action="/path/to/script.cgi" method="post" enctype="multipart/form-data" target="processing">
 <p>File to analyse: <input type="file" name="filename" size="50"/></p>
 <p><input type="submit" name="Submit" value="Analyse" /></p>
</form></font></p>

<p style="margin-left: 20"><font face="Arial" size="2" color="#000000">Analysing the file may take a while</font></p>
<iframe name="processing" width="70%" height="300">

</iframe>

CGI 脚本:

my $query = new CGI;
print $query->header(-type => 'text/plain');
function1();
function2_takesLongTime($parameter);
function3();

所以可以说“function1”只是为文件分析做一些准备(创建文件夹等)。 “function2”是大函数(可能持续 15 分钟)。它是一个 perl 程序,它有很多“打印”,由于 CGI 的“text/plain”标头,它们被重定向到 html 页面的 iframe(在程序中不使用缓冲 $|)。 httpd 被配置为超时时间远超过 15 分钟,因此它不会来自那里。 “function3”正在清理。

如果客户端停留在 html 页面上,则 CGI 脚本会完美运行。 如果客户端停止(例如用户关闭窗口),函数 1 和 2 在服务器端执行,但此后脚本似乎被中断,因为没有进行清理。

我尝试使用系统命令将“function2”作为独立程序启动,或者创建一个 perl 库并调用该库的 main 函数,它仍然以相同的方式结束。 我认为无论客户端是否停留在页面上,服务器端脚本仍然会一直运行。是不是因为CGI脚本的“text/plain”头部无法返回给客户端导致脚本中断?

如果有人能帮我解决这个问题,我将不胜感激。

【问题讨论】:

  • 看来问题出在我的“function2”中的系统调用命令。我尝试调用其他不具备系统命令的函数,即使客户端没有响应,CGI 脚本也会一直运行。我还尝试删除 CGI 标头,脚本也可以完美运行。我想这是系统调用和 CGI​​ 将标准输出实时刷新回客户端这一事实的结合,导致错误发生......

标签: perl cgi client apache


【解决方案1】:

您需要以不同的方式构建您的软件。使用某种异步编程,作业队列就可以了,而使用 CGI 程序仅将作业放入队列中。使用您已经提到的库进行转换。

您似乎对这个概念不熟悉,所以我推荐一个非常简单的:Qudo。如果您觉得它过于严格,请切换到 Gearman,我认为这是 Perl 世界中最流行的一种(参见接口 Gearman::XSGearman)。

TIMTOWTDI:如果您可以完全放弃 CGI.pm 提供的执行环境,请参阅例如Catalyst's RunAfterRequest.

【讨论】:

  • 感谢您的回复 Daxim,“TIMTOWTDI”:没错,但我的应用程序有点线性。即使我正在运行的程序很大,我也不需要多任务。此外,我真的很想了解我的 CGI 脚本发生了什么。我一直在以各种不同的方式对其进行测试,我真的很好奇这个问题。我问了我的一些同事,没有人知道它来自哪里。无论如何,谢谢,如果我写一个更大的应用程序,我一定会仔细看看 Gearman!
  • Beanstalk 是另一个不错的工作队列;我在生产代码中使用它,它非常稳定,Perl接口易于使用。
【解决方案2】:

Watching long processes through CGI 提供了解决此问题的直接方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 2013-09-23
    • 2018-03-04
    • 2015-04-27
    • 2015-10-21
    • 1970-01-01
    相关资源
    最近更新 更多