【问题标题】:Execute HTTP GET Request Without Waiting for Response [closed]执行 HTTP GET 请求而不等待响应 [关闭]
【发布时间】:2017-06-30 14:49:23
【问题描述】:

我有一个 PHP 脚本,用户将 OTP 作为 SMS 发送。我使用的 SMS 网关大约需要 5-8 秒才能响应。我不能等那么久。我需要发出请求并立即向用户发送 HTML 响应。

我使用了 curl,它花费的时间太长,并且短暂的超时会断开连接并使网关变得不可预测。我需要一种方法来发出请求,执行一些例程,最好可以选择验证请求。

【问题讨论】:

  • 是的,您正在寻找 curl_multi。 None of them work properly - 不,你只是没有正确使用它。
  • 哦,让我再试一次。它可以在不到一秒的时间内执行获取请求而无需等待吗?
  • 您能否发布一个 PHP 异步实现的示例?

标签: php curl php-7


【解决方案1】:

您使用stream_socket_client()。执行您的 GET 请求,然后稍后获取结果。

使用 stream_socket_client() 发出请求

    $host = 'www.example.com';
    $path = '/';
    $http = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
    $stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); 
    if ($stream) {
      $sockets[] = $stream;  // supports multiple sockets
      fwrite($stream, $http);
    }
    else { 
      $err .=  "$id Failed<br>\n";
    }  

使用 stream_select() 获取响应

$timeout = 120;
$buffer_size = 8192;
while (count($sockets)) {
  $read = $sockets; 
  stream_select($read, $write = NULL, $except = NULL, $timeout);
  if (count($read)) {
    foreach ($read as $r) { 
      $id = array_search($r, $sockets); 
      $data = fread($r, $buffer_size); 
      if (strlen($data) == 0) {  // done
        fclose($r); 
        unset($sockets[$id]);
      } 
      else {
        $result[$id] .= $data; // append buffer to result
      }
    }
  }
  else { 
 //   echo 'Timeout: ' . date('h:i:s') . "\n\n\n";
    break;
  }
}

更新

您可以随时提出请求,并在请求后随时得到响应。创建套接字时,$sockets 数组的键是 $id。

如果您想使用其他控制方法,则不必使用 while 循环。示例中的缓冲区为 8K。如果响应超过 8K,则需要多次读取。

如果您不想检索响应,则只需关闭套接字并且不要使用 $sockets 数组。在 fclose() 之前,您可能需要也可能不需要延迟。这取决于主机如何响应断开的连接。

$host = 'www.example.com';
$path = '/?param=value';
$http = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
$stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); 

if ($stream) {
  fwrite($stream, $http);
  fclose($stream); 

}
else { 
  $err .=  "$id Failed<br>\n";
}     

【讨论】:

  • 好吧,我不想等待回复。那么我可以跳过第二个代码吗?
  • 如果我想传递一些get参数怎么办?我应该把它们放在哪里?
  • 没问题。将查询字符串添加到 $path 的末尾。 /?param1=value1&amp;parm2=value2
  • 顺便说一句,我多年来一直在使用它,原因与您相同。您也可以调用自己的 PHP 脚本并传递参数。然后,您的脚本会执行请求以及可能需要的任何内务处理。然后延迟不会影响您的主脚本。上面的代码我从来没有失败过。
猜你喜欢
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
  • 2015-01-06
  • 1970-01-01
  • 2021-08-28
  • 2018-11-13
相关资源
最近更新 更多