diff --git a/src/AsyncClient.php b/src/AsyncClient.php new file mode 100644 index 0000000..2b0d52b --- /dev/null +++ b/src/AsyncClient.php @@ -0,0 +1,176 @@ +withMethod($method) + ->coroutine( + $this->matchHost($path), + $this->paramEncode($params) + ); + } + + + /** + * @param $path + * @return $this + */ + public function withCAInfo($path): static + { + return $this; + } + + /** + * @param $url + * @param array|string $data + * @throws Exception 使用swoole协程方式请求 + */ + private function coroutine($url, array|string $data = []): void + { + try { + $this->generate_client($data, ...$url); + if ($this->client->statusCode < 0) { + throw new Exception($this->client->errMsg); + } + $this->setStatusCode($this->client->getStatusCode()); + $this->setBody($this->client->getBody()); + $this->setResponseHeader($this->client->headers); + } catch (\Throwable $exception) { + Kiri::getDi()->get(Logger::class)->error('rpc', [$exception]); + $this->setStatusCode(-1); + $this->setBody(jTraceEx($exception)); + } + } + + + /** + * @param $data + * @param $host + * @param $isHttps + * @param $path + */ + private function generate_client($data, $host, $isHttps, $path): void + { + if ($isHttps || $this->isSSL()) { + $this->client = new SwowClient($host, 443, TRUE); + } else { + $this->client = new SwowClient($host, $this->getPort(), FALSE); + } + $this->client->set($this->settings()); + if (!empty($this->getAgent())) { + $this->withAddedHeader('User-Agent', $this->getAgent()); + } + + + $path = $this->setParams($path, $data); + + $array = []; + $array[] = strtoupper($this->getMethod()) . ' ' . $path . ' HTTP/1.1'; + if (!empty($this->getHeader())) { + foreach ($this->getHeader() as $key => $value) { + $array[] = sprintf('%s: %s', $key, $value); + } + } + + $array = implode("\r\n", $array) . "\r\n\r\n"; +// +// $array .= $data; +// + $this->client->send($array . $data); + + $revice = $this->client->recv(); + + [$header, $body] = explode("\r\n\r\n", $revice); + + $this->setBody($body); + $this->setResponseHeader(explode("\r\n", $header)); + +// +// $this->client->setHeaders($this->getHeader()); +// $this->client->setMethod(strtoupper($this->getMethod())); +// $this->client->execute($this->setParams($path, $data)); + } + + + /** + * @param $path + * @param $data + * @return string + */ + private function setParams($path, $data): string + { + if ($this->isGet()) { + if (!empty($data)) $path .= '?' . $data; + } else { + $data = $this->mergeParams($data); + if (!empty($data)) { + $this->withBody(new Stream($data)); + } + } + return $path; + } + + + /** + * + */ + public function close(): void + { + $this->client->close(); + } + + /** + * @return array + */ + #[Pure] private function settings(): array + { + $sslCert = $this->getSslCertFile(); + $sslKey = $this->getSslKeyFile(); + $sslCa = $this->getCa(); + + $params = []; + if ($this->getConnectTimeout() > 0) { + $params['timeout'] = $this->getConnectTimeout(); + } + if (empty($sslCert) || empty($sslKey) || empty($sslCa)) { + return $params; + } + + $params['ssl_host_name'] = $this->getHost(); + $params['ssl_cert_file'] = $this->getSslCertFile(); + $params['ssl_key_file'] = $this->getSslKeyFile(); + $params['ssl_verify_peer'] = TRUE; + $params['ssl_cafile'] = $sslCa; + + return $params; + } +} diff --git a/src/Client.php b/src/Client.php index cf38966..47a669d 100644 --- a/src/Client.php +++ b/src/Client.php @@ -12,7 +12,7 @@ class Client { - private CoroutineClient|Curl $abstracts; + private CoroutineClient|Curl|AsyncClient $abstracts; /** @@ -25,7 +25,7 @@ class Client if (Context::inCoroutine()) { $this->abstracts = new CoroutineClient($host, $port, $isSsl); } else { - $this->abstracts = new Curl($host, $port, $isSsl); + $this->abstracts = new AsyncClient($host, $port, $isSsl); } } diff --git a/src/ClientAbstracts.php b/src/ClientAbstracts.php index e7c3f86..00efb0b 100644 --- a/src/ClientAbstracts.php +++ b/src/ClientAbstracts.php @@ -68,7 +68,7 @@ abstract class ClientAbstracts implements IClient /** - * @var resource|\Swoole\Coroutine\Http\Client + * @var resource|\Swoole\Coroutine\Http\Client|\Swoole\Client */ protected mixed $client;