Maximisez les performances asynchrones : libérez toute la puissance de Guzzle 7 via la boucle d'événements ReactPHP pour des E/S non bloquantes
P粉043566314
P粉043566314 2024-02-17 14:29:49
0
1
501

J'ai un bot DiscordPHP et j'essaie de télécharger des pages Web qui nécessitent des cookies. Il semble que je doive utiliser le gestionnaire curl avec Guzzle car le navigateur http ReactPHP ne prend pas en charge les cookies.

J'ai créé ce script minimal :

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();

Cela se terminera immédiatement sans ajouter le code addPeriodicTimer 来检查挂起并手动调用 tick() : 

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

En utilisant la minuterie, cela fonctionne comme prévu :

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

L'idée d'utiliser tick() est venue de ce fil de discussion fermé de 73 commentaires sur github.com.

Il existe quelques questions similaires, mais aucune ne semble résoudre ce problème :

  • Faites des requêtes asynchrones à l'aide du proxy Guzzle 7, envoyez des requêtes asynchrones à l'aide de Guzzle sans attendre de réponse, utilisez le pool Guzzle au lieu des promesses guzzle et comment envoyer plusieurs requêtes à la fois ReactPHP ? Utilisez tout wait() Il s’agit d’un appel bloquant.
  • ReactPHP promet une exécution synchrone à l'aide de boucles sleep() 调用,ReactPHP 真的是异步的吗?执行一个长 for. Les deux bloquent la boucle.
  • Pour les requêtes parallèles, Guzzle, ReactPHP et Amphp ainsi que Guzzle et React Promise entraînent des boucles infinies utilisant des versions plus anciennes de Guzzle ou du code obsolète qui ne fonctionne pas correctement dans Guzzle 7.

Comment utiliser Cookie Jar pour lancer HTTP GET et obtenir une réponse dans la boucle d'événements ReactPHP sans utiliser d'appels bloquants (tels que ->wait() ou manuel GET 并在 ReactPHP 事件循环中获取响应,而不使用阻塞调用(例如 ->wait() 或手动 tick()ing curl

P粉043566314
P粉043566314

répondre à tous(1)
P粉384366923

Eh bien, ReactPHP ne définit pas les cookies automatiquement, il existe déjà un ticket traitant de ce sujet : https://github.com/reactphp/http/issues/445, mais vous pouvez toujours définir l'en-tête du cookie HTTP manuellement.

Il convient également de mentionner que l'utilisation de ReactPHP avec Guzzle ne fonctionnera pas car Guzzle bloque la boucle d'événements de ReactPHP. Cela signifie que vous pouvez envoyer plusieurs requêtes, mais que vous ne pouvez rien faire d'autre de manière asynchrone.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal