Php Zend HttpClient更精确的超时?
ZendFramework2的各种http客户端适配器似乎允许连接和读取超时在秒范围内;通过在设置各种超时参数之前将其强制转换为(int)。在我们的组织中,我们通常为生产环境指定较小的连接和读取超时(我们有一个SOA) 但是,php中的套接字级别函数支持超时值(float)以支持次秒超时,并且自PHP5.2.3以来,有一些方法可以使用libcurl支持次秒连接超时。(CULLOPT_连接超时_MS,CULL符合c-ares per)Php Zend HttpClient更精确的超时?,php,curl,zend-framework2,Php,Curl,Zend Framework2,ZendFramework2的各种http客户端适配器似乎允许连接和读取超时在秒范围内;通过在设置各种超时参数之前将其强制转换为(int)。在我们的组织中,我们通常为生产环境指定较小的连接和读取超时(我们有一个SOA) 但是,php中的套接字级别函数支持超时值(float)以支持次秒超时,并且自PHP5.2.3以来,有一些方法可以使用libcurl支持次秒连接超时。(CULLOPT_连接超时_MS,CULL符合c-ares per) 我很高兴进入ZendFramework,以支持更小、更细粒度的
我很高兴进入ZendFramework,以支持更小、更细粒度的超时,但我想先看看这是否是一个“野外”解决的问题。有人使用Zend\Http\Client\Adapter\Socket或\Curl适配器来支持亚秒级的连接和读取超时吗?我知道两种解决问题的方法。您可以将用作临时修复程序,直到Zend Framework 2自己支持次秒超时
套接字
/Curl
类
创建模块并从Socket
/Curl
类继承,并重写connect()
方法以支持亚秒超时
对于Curl
类,我将在配置数组中添加一个新选项timeout\u ms
,因此您仍然可以使用旧的timeout
选项我的代码仅显示超时部分的相关更改。
<?php
use Zend\Http\Client\Adapter\Curl;
class CurlMs extends Curl
{
public function connect($host, $port = 80, $secure = false)
{
...
// Replace the lines with timeout with the following lines.
if (isset($this->config['timeout_ms'])) {
// Set timeout milliseconds
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, $this->config['timeout_ms']);
} elseif (isset($this->config['timeout'])) {
// Set timeout
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $this->config['timeout']);
}
...
}
}
<?php
use Zend\Http\Client\Adapter\Socket;
class SocketMs extends Socket
{
public function connectconnect($host, $port = 80, $secure = false)
{
...
// Replace the lines with socket connect
$this->socket = stream_socket_client(
$host . ':' . $port,
$errno,
$errstr,
(float) $this->config['timeout'],
$flags,
$context
);
...
// Replace the lines with stream timeout
// get the fraction of the float value and convert it microseconds
$fraction = ($this->config['timeout'] - floor($this->config['timeout'])) * 1000;
// Set the stream timeout
if (!stream_set_timeout($this->socket, (int) $this->config['timeout'], (int) $fraction) {
throw new AdapterException\RuntimeException('Unable to set the connection timeout');
}
...
}
}
Socket.php
/Curl.php
文件
为要添加次秒超时的文件编写修补程序,并将其应用于ZendFramework 2版本。如果使用,您可以使用自动化流程。我创建了针对服务器的补丁
我不推荐这种方法,因为它有一些缺陷。
<?php
use Zend\Http\Client\Adapter\Curl;
class CurlMs extends Curl
{
public function connect($host, $port = 80, $secure = false)
{
...
// Replace the lines with timeout with the following lines.
if (isset($this->config['timeout_ms'])) {
// Set timeout milliseconds
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, $this->config['timeout_ms']);
} elseif (isset($this->config['timeout'])) {
// Set timeout
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $this->config['timeout']);
}
...
}
}
<?php
use Zend\Http\Client\Adapter\Socket;
class SocketMs extends Socket
{
public function connectconnect($host, $port = 80, $secure = false)
{
...
// Replace the lines with socket connect
$this->socket = stream_socket_client(
$host . ':' . $port,
$errno,
$errstr,
(float) $this->config['timeout'],
$flags,
$context
);
...
// Replace the lines with stream timeout
// get the fraction of the float value and convert it microseconds
$fraction = ($this->config['timeout'] - floor($this->config['timeout'])) * 1000;
// Set the stream timeout
if (!stream_set_timeout($this->socket, (int) $this->config['timeout'], (int) $fraction) {
throw new AdapterException\RuntimeException('Unable to set the connection timeout');
}
...
}
}
Curl.php
文件的修补程序如下所示:
--- a/library/Zend/Http/Client/Adapter/Curl.php
+++ b/library/Zend/Http/Client/Adapter/Curl.php
@@ -200,7 +200,10 @@ class Curl implements HttpAdapter, StreamInterface
curl_setopt($this->curl, CURLOPT_PORT, intval($port));
}
- if (isset($this->config['timeout'])) {
+ if (isset($this->config['timeout_ms'])) {
+ // Set timeout milliseconds
+ curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, $this->config['timeout_ms']);
+ } elseif (isset($this->config['timeout'])) {
// Set timeout
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $this->config['timeout']);
}
Socket.php
文件的补丁如下:
--- a/library/Zend/Http/Client/Adapter/Socket.php
+++ b/library/Zend/Http/Client/Adapter/Socket.php
@@ -247,7 +247,7 @@ class Socket implements HttpAdapter, StreamInterface
$host . ':' . $port,
$errno,
$errstr,
- (int) $this->config['timeout'],
+ (float) $this->config['timeout'],
$flags,
$context
);
@@ -268,7 +268,9 @@ class Socket implements HttpAdapter, StreamInterface
}
// Set the stream timeout
- if (!stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
+ // get the fraction of the timeout and convert it to microseconds
+ $fraction = ($this->config['timeout'] - floor($this->config['timeout'])) * 1000;
+ if (!stream_set_timeout($this->socket, (int) $this->config['timeout'], (int) $fraction)) {
throw new AdapterException\RuntimeException('Unable to set the connection timeout');
}