通过Socket执行
array Core_HttpCall::exec_by_socket( array $hosts , string $url , string $path_info [, array $param_arr = null ] )
参数列表
参数 类型 描述 默认值 $hosts
array
请求的所有服务器列表 $url
string
请求的URL $path_info
string
待请求的 path_info 参数 $param_arr
array
请求的参数 null
array
protected static function exec_by_socket($hosts, $url, $path_info, array $param_arr = null)
{
$vars = http_build_query($param_arr);
if (preg_match('#^(http(?:s)?)\://([^/\:]+)(\:[0-9]+)?/(.*)$#', $url, $m))
{
$uri = '/'.ltrim($m[4],'/'); //获取到URI部分
$h = $m[2]; //获取到HOST
}
$fs = $errno = $errstr = $rs = array();
foreach ($hosts as $host)
{
list($hostname, $port) = explode(':', $host, 2);
if (!$port)
{
$port = $_SERVER["SERVER_PORT"];
}
if ($m[1]=='https')$hostname = 'tls://' . $hostname;
# 一个mictime
$mictime = microtime(1);
# 生成一个随机字符串
$rstr = Text::random();
# 生成一个HASH
$hash = self::get_hash($vars, $rstr, $mictime, $path_info .'_'. (IS_ADMIN_MODE?1:0) .'_'. (IS_REST_MODE?1:0));
# 使用HTTP协议请求数据
$str = 'POST ' . $uri . ' HTTP/1.0' . CRLF
. 'Host: ' . $h . CRLF
. 'User-Agent: MyQEE System Call' . CRLF
. 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' . CRLF
. 'Connection: close' . CRLF
. 'X-Myqee-System-Hash: ' . $hash . CRLF
. 'X-Myqee-System-Time: ' . $mictime . CRLF
. 'X-Myqee-System-Rstr: ' . $rstr . CRLF
. 'X-Myqee-System-Pathinfo: '.$path_info . CRLF
. 'X-Myqee-System-Project: '.Core::$project . CRLF
. 'X-Myqee-System-Isadmin: '.(IS_ADMIN_MODE?1:0) . CRLF
. 'X-Myqee-System-Isrest: '.(IS_REST_MODE?1:0) . CRLF
. 'X-Myqee-System-Debug: ' . (IS_DEBUG?1:0) . CRLF
. 'Content-Length: ' . strlen($vars) . CRLF
. 'Content-Type: application/x-www-form-urlencoded' . CRLF
. CRLF . $vars;
// 尝试2次
for( $i=1 ;$i<3 ;$i++ )
{
if (isset($fs[$host]))break;
# 尝试连接服务器
$ns = fsockopen($hostname, $port, $errno[$host], $errstr[$host], 1);
if ($ns)
{
$fs[$host] = $ns;
break;
}
elseif ($i==2)
{
$rs[$host] = false;
}
else
{
usleep(2000); //等待2毫秒
}
}
unset($ns);
if ($fs[$host])
{
for($i=0;$i<3;$i++)
{
# 写入HTTP协议内容
if (strlen($str) === fwrite($fs[$host], $str))
{
# 成功
break;
}
elseif ($i==2)
{
# 写入失败,将此移除
unset($fs[$host]);
$rs[$host] = false;
break;
}
else
{
usleep(2000); //等待2毫秒
}
}
}
}
foreach ($fs as $host=>$f)
{
$str = '';
while (!feof($f))
{
$str .= fgets($f);
}
fclose($f);
list($header,$body) = explode("\r\n\r\n", $str, 2);
$rs[$host] = $body;
}
return $rs;
}