PoolHandler.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Guzzle\RingPHP;
  12. use Exception;
  13. use GuzzleHttp\Ring\Core;
  14. use GuzzleHttp\Ring\Exception\RingException;
  15. use Hyperf\Engine\Http\Client;
  16. use Hyperf\Pool\SimplePool\PoolFactory;
  17. class PoolHandler extends CoroutineHandler
  18. {
  19. public function __construct(protected PoolFactory $factory, array $option = [])
  20. {
  21. parent::__construct($option);
  22. }
  23. public function __invoke($request)
  24. {
  25. $method = $request['http_method'] ?? 'GET';
  26. $scheme = $request['scheme'] ?? 'http';
  27. $ssl = $scheme === 'https';
  28. $body = $request['body'] ?? '';
  29. $effectiveUrl = Core::url($request);
  30. $params = parse_url($effectiveUrl);
  31. $host = $params['host'];
  32. if (! isset($params['port'])) {
  33. $params['port'] = $this->getPort($request, $ssl);
  34. }
  35. $port = $params['port'];
  36. $path = $params['path'] ?? '/';
  37. if (isset($params['query']) && is_string($params['query'])) {
  38. $path .= '?' . $params['query'];
  39. }
  40. $pool = $this->factory->get($this->getPoolName($host, $port), function () use ($host, $port, $ssl) {
  41. return $this->makeClient($host, $port, $ssl);
  42. }, $this->options);
  43. $connection = $pool->get();
  44. $response = null;
  45. try {
  46. /** @var Client $client */
  47. $client = $connection->getConnection();
  48. // Init Headers
  49. $headers = $this->initHeaders($request);
  50. $settings = $this->getSettings($this->options);
  51. if (! empty($settings)) {
  52. $client->set($settings);
  53. }
  54. $beginTime = microtime(true);
  55. try {
  56. $raw = $client->request($method, $path, $headers, (string) $body);
  57. } catch (Exception $exception) {
  58. $connection->close();
  59. $exception = new RingException($exception->getMessage());
  60. return $this->getErrorResponse($exception, $beginTime, $effectiveUrl);
  61. }
  62. $response = $this->getResponse($raw, $beginTime, $effectiveUrl);
  63. } finally {
  64. $connection->release();
  65. }
  66. return $response;
  67. }
  68. protected function getPoolName($host, $port)
  69. {
  70. return sprintf('guzzle.ring.handler.%s.%d', $host, $port);
  71. }
  72. }