有没有办法让HTTP::Daemon
以某种方式检测客户端何时断开连接(例如由于超时),然后自行终止?
现在,这就是我编写服务器的方式:
my $response;
try {
local $SIG{ALRM} = sub { die __TIMEOUT__ };
alarm 180;
&process_query;
alarm 0;
$response = new HTTP::Response(200);
}
catch {
if ( $_ eq __TIMEOUT__ ) {
$response = new HTTP::Response(504);
}
else {
$response = new HTTP::Response(500);
}
};
$client->send_response($response);
这只是假设客户端将在180秒后放弃,这可能是也可能不是。只要客户端一直等待响应,我想继续处理,但不会更长。
答案 0 :(得分:1)
通常只要处理数据(单线程)就不会检查文件描述符,因此它不会检测到问题。我看到以下选项:
process_query
或类似内容可以读取$client
套接字,请在IO::Select
内查看。可读的可以是客户端关闭连接或者它发送更多数据,例如HTTP流水线。您可以尝试使用recv
和MSG_PEEK
检查是否有数据或eof(例如客户端关闭),但是您将无法检测是否有更多数据后跟eof,因为您首先拥有在获得eof之前阅读数据。fcntl($client,F_SETOWN,$$)
套接字上有新事件,您可以使内核向您发送SIGIO
信号。但是我最后一次使用这个Perl时没有正确处理它,我不得不通过显式调用$client
- syscall:fcntl
来解决它。设置完成后,您可以像处理syscall(SYS_fcntl,fileno($client),F_SETOWN,$$);
一样处理IO
信号。在任何情况下:来自客户端的eof仅表示客户端将不再写入(请求结束)。它可能仍然愿意读取您的数据(单向关闭)。只有在发送数据并获得ALRM
后,您才能知道客户端是否已关闭以进行读取。没有办法绕过它,这就是带有BSD套接字的TCP的工作方式。