【问题标题】:Detect android java client connection timeout from PHP从PHP检测android java客户端连接超时
【发布时间】:2012-01-10 18:06:22
【问题描述】:

我从一个使用 java 的 android 设备连接到一个使用 DefaultHttpClient 运行 PHP 的服务器。

我正在做的一个测试是检查 java 代码是否优雅地处理自己,如果服务器需要很长时间来发送数据。如果确实需要很长时间,它会断开连接并重试。

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

HttpConnectionParams.setSoTimeout(httpParameters, 3000);

在服务器上,PHP 脚本正在休眠 10 秒:

sleep(10);

java 代码有效,如果脚本花费的时间超过 3 秒,那么它会抛出 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 一条简单的线路让你睡 10 秒。
  • @Phil 我已经尝试使用 connection_aborted

标签: java php android http


【解决方案1】:

其实我不久前就写了一篇关于这个主题的文章,我在这里做一个简单的回答,并假设也可以发布相关链接?

本质上,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/

问候, 菲尔,

【讨论】:

  • 不错的文章值得阅读并感谢您的回答。我已经推出了代码,所以我可能需要一些时间来测试你的想法。
【解决方案2】:

不确定现在是否相同,但很久以前我遇到过 php,直到它实际尝试写入或刷新其输出缓冲区时才意识到连接已中止。参见 php 的 flush() 和 ob_flush();我实际上不需要写任何东西来输出,只需刷新空缓冲区就足以让它检查。

我想 webserver(s) 和 php 前面的其他东西可能会影响这种行为。

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

【讨论】:

  • 是的,这似乎指向了简单的睡眠脚本没有输出任何东西的事实。让我们看看在connection_abort函数触发它之前是否调用flush。
【解决方案3】:
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 秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 2014-04-14
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多