从PHP检测Android Java客户端连接超时

5

我正在使用Java从一个Android设备连接到运行PHP的服务器,使用DefaultHttpClient。

我进行的一个测试是检查Java代码是否能够优雅地处理如果服务器在发送数据时需要很长时间。如果确实需要很长时间,则会断开连接并重试。

目前,我已经通过以下方式将连接超时设置为3秒:

HttpConnectionParams.setSoTimeout(httpParameters, 3000);

在服务器上,PHP脚本会睡眠10秒钟:

sleep(10);

如果脚本运行时间超过3秒,则Java代码会抛出java.net.SocketTimeoutException异常,然后在短时间内重新尝试。

PHP脚本继续运行,这不是我想要的。我尝试在sleep函数之后立即使用connection_aborted进行测试,但它无法捕获已经发生的客户端断开连接。

ignore_user_abort(true);
sleep(10);
print "black hole";
flush();
if(connection_aborted()!=0){
        // You would think this works but it does not.
}

什么是处理这个问题的推荐方法?

相关的 PHP 代码是什么样子的? - Phil
@Phil 一行简单的代码来让程序休眠10秒钟。 - zaf
@Phil 我已经使用connection_aborted尝试了我的努力。 - zaf
3个回答

2
我实际上不久前就这个问题写了一篇文章,我将在这里给出简短的答案,并假设也可以发布相关链接?
基本上,当PHP尝试使用连接到远程套接字的套接字时,它才会发现远程客户端已断开连接。在您要求它执行与该套接字有关的任何操作之前,它将认为一切正常。以下是我用于检查远程断开连接的代码:
public function isAlive(){
        $res = @socket_recv($this->sockHandle, $data, 1024, MSG_PEEK);
        if($res === 0){
        return false;
        }else{
        return true;
        }
}

这里的重要部分是 MSG_PEEK 停止清除任何待处理的消息,并且 "@" 在套接字正常但没有待处理消息时静音错误。
完整文章在此处可用:

http://www.bracketbrotherhood.com/remote-disconnections-php-non-blocking-server-sockets/programming-and-development/

问候, 菲尔,

很棒的文章,感谢您的回答。我已经推出了代码,所以测试您的想法可能需要一些时间。 - zaf

0

不确定现在是否仍然如此,但很久以前我遇到了 PHP 的问题,直到它实际尝试写入或刷新其输出缓冲区时才意识到连接已中止。请参阅 PHP 的 flush() 和 ob_flush();我不需要实际写任何输出,只需刷新空缓冲区就足以使其检查。

我想 Web 服务器和其他在 PHP 前面的东西可能会影响这种行为。

您可能需要已经调用 ignore_user_abort(true); 否则,PHP 在 flush() 调用时可能会停止执行(默认行为是在意识到连接已断开时停止),因此您的 if 语句将永远不会被执行。


是的,看起来这似乎表明简单的睡眠脚本没有输出任何内容。让我们看看在 connection_abort 函数之前调用 flush 是否会触发它。 - zaf

-1
print
"black hole";
flush();
if(connection_aborted()!=0){
      // You would think this works but it does not.
   }

实际上,你可能不会想到这样做会有效,因为它需要 PHP 脚本在脚本中达到那个点。如果你把它写在最后,那么脚本必须按照其流程运行。
我建议改为:
for($i=0;$i<10;$i++){
    echo ' '; ## echo "\0";  might also work
    flush();
    if(connection_aborted()!=0){
          // You would think this works but maybe it will now.
          die();
       }
     sleep(1); # the sleep should come after the check
}

试一试吧。显然,你正在尝试睡眠10秒钟,然后终止脚本... 在所有情况下,该脚本将运行10秒钟。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接