dispatch($domain, $path, 'GET', $params, $timeout); return new Result(['code' => 0, 'data' => $request]); } /** * @param $domain * @param $path * @param array $params * @param int $timeout * @return Result * @throws Exception */ public function post($domain, $path, $params = [], $timeout = -1): Result { $request = $this->dispatch($domain, $path, 'POST', $params, $timeout); return new Result(['code' => 0, 'data' => $request]); } /** * @param $domain * @param $path * @param array $params * @param int $timeout * @return Result * @throws Exception */ public function upload($domain, $path, $params = [], $timeout = -1): Result { $request = $this->dispatch($domain, $path, 'POST', $params, $timeout, true); return new Result(['code' => 0, 'data' => $request]); } /** * @param $domain * @param $path * @param array $params * @param int $timeout * @return Result * @throws Exception */ public function delete($domain, $path, $params = [], $timeout = -1): Result { $request = $this->dispatch($domain, $path, 'DELETE', $params, $timeout); return new Result(['code' => 0, 'data' => $request]); } /** * @param $domain * @param $path * @param $method * @param array $params * @param int $timeout * @param bool $isUpload * @return mixed * @throws ComponentException * @throws NotFindClassException * @throws ReflectionException * @throws Exception */ private function dispatch($domain, $path, $method, $params = [], $timeout = -1, $isUpload = false): mixed { $client = $this->getClient($domain, $timeout); $request = $this->getRequest($domain, $path, $method, $params, $isUpload); $client->send($request); defer(function () use ($domain, $path, $client, $request, $method) { $pool = Snowflake::app()->getChannel(); $pool->push($request, 'request.' . $method . $path); $pool->push($client, 'http2.' . $domain); }); return Help::toArray($client->recv()); } /** * @param $domain * @param $path * @param array $params * @param int $timeout * @return mixed * @throws Exception */ public function put($domain, $path, $params = [], $timeout = -1): Result { $request = $this->dispatch($domain, $path, 'PUT', $params, $timeout); return new Result(['code' => 0, 'data' => $request]); } /** * @param $domain * @param $path * @param $method * @param $params * @param bool $isUpload * @return Request * @throws ReflectionException * @throws ComponentException * @throws NotFindClassException */ public function getRequest($domain, $path, $method, $params, $isUpload = false): Request { if (!str_starts_with($path, '/')) { $path = '/' . $path; } $channel = Snowflake::app()->getChannel(); $request = $channel->pop('request.' . $method . $path, function () use ($path, $method) { $request = new Request(); $request->method = $method; $request->path = $path; return $request; }); if ($method === 'GET') { $request->path .= '?' . http_build_query($params); } else { $request->data = !is_string($params) && !$isUpload ? Json::encode($params) : $params; } $request->headers = [ 'host' => $domain, 'user-agent' => 'Chrome/49.0.2587.3', 'accept' => 'text/html,application/json', 'accept-encoding' => 'gzip' ]; $headers = Context::getContext('http2Headers'); if (!empty($headers) && is_array($headers)) { $request->headers = array_merge($request->headers, $headers); } return $request; } /** * @param $domain * @param int $timeout * @return H2Client * @throws Exception */ private function getClient($domain, $timeout = -1): H2Client { $pool = Snowflake::app()->getChannel(); /** @var H2Client $client */ $client = $pool->pop('http2.' . $domain, function () use ($domain, $timeout) { $domain = rtrim($domain, '/'); $replace = str_replace('https://', '', $domain); $replace = str_replace('http://', '', $replace); if (str_starts_with($domain, 'https')) { $client = new H2Client($replace, 443, true); } else if (str_contains($replace, ':')) { [$host, $port] = explode(':', $replace); $client = new H2Client($host, $port, false); } else { $client = new H2Client($replace, 80, false); } $client->set([ 'timeout' => $timeout, 'ssl_host_name' => $domain ]); return $client; }); if (!$client->connected && !$client->connect()) { throw new Exception('Http connected fail.'); } return $client; } }