代码之家  ›  专栏  ›  技术社区  ›  Vilx-

如何在不阻塞的情况下处理GuzzleHTTP异步请求?

  •  1
  • Vilx-  · 技术社区  · 7 年前

    我需要编写一个处理器,它可能向外部服务发送许多HTTP请求。因为我想最大限度地提高性能,所以我希望最小化阻塞。我使用的是PHP5.6和GuzzyHTTP。

    GuzzyHTTP没有异步请求选项。但是由于我们在PHP中只有1个线程可用,所以我需要为它们分配一些时间来进行处理。不幸的是,我只看到一种方法-打电话 wait 在处理所有请求之前都会阻塞。这不是我想要的。

    相反,我想要一些方法来处理已经到达的内容,然后返回。这样我就可以做一些事情:

    $allRequests = [];
    
    while ( !checkIfNeedToEnd() ) {
        $newItems = getItemsFromQueue();
        $allRequests = $allRequests + spawnRequests($newItems);
        GuzzleHttp::processWhatYouCan($allRequests);
        removeProcessedRequests($allRequests);
    }
    

    这有可能吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Vilx-    7 年前

    $handler = new \GuzzleHttp\Handler\CurlMultiHandler();
    $client = new \GuzzleHttp\Client(['handler' => $handler]);
    $promise1 = $client->getAsync("http://www.stackoverflow.com");
    $promise2 = $client->getAsync("http://localhost/");
    
    $doneCount = 0;
    
    $promise1->then(function() use(&$doneCount) {
        $doneCount++;
        echo 'Promise 1 done!';
    });
    $promise2->then(function() use(&$doneCount) {
        $doneCount++;
        echo 'Promise 2 done!';
    });
    
    $last = microtime(true);
    while ( $doneCount < 2 ) {
        $now = microtime(true);
        $delta = round(($now-$last)*1000);
        echo "tick($delta) ";
        $last = $now;
    
        $handler->tick();
    }
    

    CurlMultiHandler tick()

    $handler = new \GuzzleHttp\Handler\CurlMultiHandler(['select_timeout' => 0.5]);