I have a DiscordPHP bot that I'm trying to download some web pages that require a cookie. It seems I need to use a curl handler with Guzzle because the ReactPHP http browser doesn't support cookies.
I've 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 exits immediately without the code adding the addPeriodicTimer
to check pending and call tick()
manually:
$ time php minimal.php
0.022u 0.010s 0:00.03 100.0% 0+0k 0+0io 67pf+0w
With the 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 a tick()
came from this 73 comment closed thread on github.com.
There are some similar questions, but none of them seem to address this issue:
- Asynchronous requests using proxy with Guzzle 7, Send asynchronous request without waiting the response using guzzle, Use Guzzle pool instead of guzzle promises, and How to send multiple requests at once ReactPHP? all use
wait()
which is a blocking call. - ReactPHP promises executed synchoniously uses a
sleep()
call and Is ReactPHP truly asynchronous? does a longfor
loop. Both are blocking the loop. - Guzzle vs ReactPHP vs Amphp for parallel requests and Guzzle and react Promise cause infine loop use older versions of Guzzle or deprecated code that doesn't work the same in Guzzle 7.
How do I start a HTTP GET
with a cookie jar and get the response in a ReactPHP event loop without using a blocking call such as ->wait()
or manually tick()
ing curl's handler?