Maksimumkan prestasi tak segerak: Lepaskan kuasa penuh Guzzle 7 melalui gelung acara ReactPHP untuk I/O tidak menyekat
P粉043566314
P粉043566314 2024-02-17 14:29:49
0
1
494

Saya mempunyai bot DiscordPHP dan saya cuba memuat turun beberapa halaman web yang memerlukan kuki. Nampaknya saya perlu menggunakan pengendali curl dengan Guzzle kerana pelayar ReactPHP http tidak menyokong kuki.

Saya mencipta skrip minimum ini:

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

Ini akan keluar serta-merta tanpa menambah kod addPeriodicTimer 来检查挂起并手动调用 tick():

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

Menggunakan pemasa, ia berfungsi seperti yang diharapkan:

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

Idea untuk menggunakan tick() datang daripada urutan tertutup 73 ulasan ini di github.com.

Ada beberapa soalan yang serupa, tetapi nampaknya tiada satu pun menyelesaikan masalah ini:

  • Buat permintaan asynchronous menggunakan proksi Guzzle 7, Hantar permintaan asynchronous menggunakan Guzzle tanpa menunggu jawapan, Gunakan Guzzle pool dan bukannya guzzle promises dan Bagaimana untuk menghantar berbilang permintaan sekaligus ReactPHP? Gunakan semua wait() ​​Ini adalah panggilan menyekat.
  • ReactPHP menjanjikan pelaksanaan segerak menggunakan sleep() 调用,ReactPHP 真的是异步的吗?执行一个长 for gelung. Kedua-duanya menyekat gelung.
  • Untuk permintaan selari, Guzzle, ReactPHP dan Amphp serta Guzzle dan React Promise menghasilkan gelung tak terhingga menggunakan versi lama Guzzle atau kod yang tidak digunakan yang tidak berfungsi dengan betul dalam Guzzle 7.

Cara menggunakan balang kuki untuk memulakan HTTP GET dan mendapatkan respons dalam gelung acara ReactPHP tanpa menggunakan panggilan menyekat (seperti ->wait() atau manual GET 并在 ReactPHP 事件循环中获取响应,而不使用阻塞调用(例如 ->wait() 或手动 tick()ing curl

P粉043566314
P粉043566314

membalas semua(1)
P粉384366923

Nah, ReactPHP tidak menetapkan kuki secara automatik, sudah ada tiket membincangkan topik ini: https://github.com/reactphp/http/issues/445, tetapi anda masih boleh menetapkan pengepala kuki HTTP secara manual.

Perlu juga dinyatakan bahawa menggunakan ReactPHP dengan Guzzle tidak akan berfungsi kerana Guzzle menyekat gelung acara ReactPHP. Ini bermakna anda boleh menghantar berbilang permintaan, tetapi tidak boleh melakukan apa-apa lagi secara tak segerak.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!