Home  >  Q&A  >  body text

Maximize asynchronous performance: Unleash the full power of Guzzle 7 via the ReactPHP event loop for non-blocking I/O

I have a DiscordPHP bot and I'm trying to download some web pages that require cookies. It seems that I need to use curl handler with Guzzle because ReactPHP http browser does not support cookies.

I created this minimal script:

use GuzzleHttp\Client;
use GuzzleHttp\Handler\CurlMultiHandler;
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\ResponseInterface;

include 'vendor/autoload.php';

$loop = \React\EventLoop\Loop::get();

$curl = new CurlMultiHandler;
$handler = HandlerStack::create($curl);
$client = new Client( [ /* 'cookies' => $cookieJar, */ 'handler' => $handler ] );

$promise = $client->getAsync('https://httpstat.us/200')
    ->then(
        function (ResponseInterface $res) {
            echo 'response: ' . $res->getStatusCode() . PHP_EOL;
        },
        function (\Exception $e) {
            echo $e->getMessage() . PHP_EOL;
        }
    );


$timer = $loop->addPeriodicTimer(0.5, function () use ($curl, $promise) {
    if ($promise->getState() === 'pending') {
    echo 'Tick ';
    $curl->tick();
    }
    echo 'Beat ';
});

$loop->run();

This will exit immediately without adding addPeriodicTimer to check for hangs and manually calling tick():

$ time php minimal.php
0.022u 0.010s 0:00.03 100.0%    0+0k 0+0io 67pf+0w

Using a timer, it works as expected:

Tick Beat Tick Beat Tick Beat Tick Beat Tick Beat Tick Beat Tick response: 200
Beat Beat Beat ...

The idea to use tick() came from this 73-comment closed thread on github.com.

There are some similar questions, but none seem to solve this problem:

How to use cookie jar to initiate HTTP GET and get the response in the ReactPHP event loop without using blocking calls (such as ->wait() or manuallytick()ing curl handler?

P粉043566314P粉043566314219 days ago459

reply all(1)I'll reply

  • P粉384366923

    P粉3843669232024-02-18 11:41:28

    Well, ReactPHP does not set cookies automatically, there is already a ticket discussing this topic: https://github.com/reactphp/http/issues/445, but you can still set it manually HTTP cookie header.

    It’s also worth mentioning that using ReactPHP with Guzzle won’t work because Guzzle blocks ReactPHP’s event loop. This means you can send multiple requests, but you can't do anything else asynchronously.

    reply
    0
  • Cancelreply