This commit is contained in:
2021-04-28 19:16:34 +08:00
parent 81fdf7e929
commit 9065f92831
+58 -19
View File
@@ -7,6 +7,7 @@ namespace HttpServer\Client;
use Exception; use Exception;
use HttpServer\Http\Context; use HttpServer\Http\Context;
use Snowflake\Abstracts\Component; use Snowflake\Abstracts\Component;
use Snowflake\Channel;
use Snowflake\Core\Json; use Snowflake\Core\Json;
use Snowflake\Core\Xml; use Snowflake\Core\Xml;
use Snowflake\Snowflake; use Snowflake\Snowflake;
@@ -23,6 +24,21 @@ class Http2 extends Component
{ {
private array $_clients = [];
private Channel $channel;
/**
* @throws Exception
*/
public function init()
{
$this->channel = Snowflake::getApp('channel');
}
/** /**
* @param bool $isRecv * @param bool $isRecv
* @return Http2 * @return Http2
@@ -132,30 +148,53 @@ class Http2 extends Component
*/ */
private function dispatch($domain, $path, $method, $params = [], $timeout = -1, $isUpload = false): mixed private function dispatch($domain, $path, $method, $params = [], $timeout = -1, $isUpload = false): mixed
{ {
$ssl = false; [$domain, $isSsl] = $this->clear($domain);
if (str_starts_with($domain, 'https://')) {
$domain = str_replace('https://', '', $domain);
$ssl = true;
} else if (str_starts_with($domain, 'http://')) {
$domain = str_replace('http://', '', $domain);
}
$client = $this->getClient($domain, $ssl, $timeout);
$request = $this->getRequest($path, $method, $params, $isUpload); $request = $this->getRequest($path, $method, $params, $isUpload);
$request->headers = array_merge($request->headers, [ $request->headers = array_merge($request->headers, [
'Host' => $domain 'Host' => $domain
]); ]);
defer(function () use ($domain, $path, $request, $method) {
$client->send($request); $this->channel->push($request, 'request.' . $method . $path);
defer(function () use ($domain, $path, $client, $request, $method) {
$pool = Snowflake::app()->getChannel();
$pool->push($request, 'request.' . $method . $path);
$pool->push($client, 'http2.' . $domain);
}); });
return $this->doRequest($request, $domain, $isSsl, $timeout);
}
/**
* @param $domain
* @return array
*/
private function clear($domain): array
{
if (str_starts_with($domain, 'https://')) {
return [str_replace('https://', '', $domain), true];
} else {
return [str_replace('http://', '', $domain), false];
}
}
/**
* @param Request $request
* @param $domain
* @param $ssl
* @param $timeout
* @return mixed
* @throws Exception
*/
private function doRequest(Request $request, $domain, $ssl, $timeout): mixed
{
$client = $this->getClient($domain, $ssl, $timeout);
defer(function () use ($client, $domain) {
$this->channel->push($client, 'http2.' . $domain);
});
$client->send($request);
if (Context::getContext('http2isRecv') === false) { if (Context::getContext('http2isRecv') === false) {
return null; return null;
} }
return $this->recv($client); return $this->recv($client);
} }
@@ -241,6 +280,9 @@ class Http2 extends Component
*/ */
private function getClient($domain, $isSsl = false, $timeout = -1): H2Client private function getClient($domain, $isSsl = false, $timeout = -1): H2Client
{ {
if (isset($this->_clients[$domain])) {
return $this->_clients[$domain];
}
$pool = Snowflake::app()->getChannel(); $pool = Snowflake::app()->getChannel();
/** @var H2Client $client */ /** @var H2Client $client */
$client = $pool->pop('http2.' . $domain, function () use ($domain, $isSsl, $timeout) { $client = $pool->pop('http2.' . $domain, function () use ($domain, $isSsl, $timeout) {
@@ -254,13 +296,10 @@ class Http2 extends Component
$client->set(['timeout' => $timeout, 'ssl_host_name' => $domain]); $client->set(['timeout' => $timeout, 'ssl_host_name' => $domain]);
return $client; return $client;
}); });
if ($client->connected && $client->ping()) { if ((!$client->connected || !$client->ping()) && !$client->connect()) {
return $client;
}
if (!$client->connect()) {
throw new Exception($client->errMsg, $client->errCode); throw new Exception($client->errMsg, $client->errCode);
} }
return $client; return $this->_clients[$domain] = $client;
} }