使用 guzzle 发送异步请求而不等待响应

问题描述 投票:0回答:5

我有以下两个功能

public function myEndpoint(){
    $this->logger->debug('Started');
    $this->guzzle->requestAsync('post', 'http://myurl.com/doNotWait')->wait();
    $this->logger->debug("I shouldn't wait");
}

public function doNotWait(){
    sleep(10);
    $this->logger->debug("You shouldn't wait");
}

现在我需要在日志中看到的是:

Started
I shouldn't wait
You shouldn't wait

但是我所看到的

Started
You shouldn't wait
I shouldn't wait

我还尝试使用以下方法:

方式#1

public function myEndpoint(){
    $this->logger->debug('Started');
    $this->guzzle->requestAsync('post', 'http://myurl.com/doNotWait', ['synchronous' => false])->wait();
    $this->logger->debug("I shouldn't wait");
}

方式#2

public function myEndpoint(){
    $this->logger->debug('Started');
    $this->guzzle->requestAsync('post', 'http://myurl.com/doNotWait');

    $queue = \GuzzleHttp\Promise\queue()->run();
    $this->logger->debug("I shouldn't wait");
}

但结果却永远不是想要的。任何想法?我正在使用 Guzzle 6.x。

php asynchronous guzzle guzzle6
5个回答
12
投票

将其从未答复列表中删除:


如果没有深度黑客攻击,Guzzle 不支持“即发即忘”异步请求。

异步方法是

Client::requestAsync()
的抽象,它返回一个承诺。请参阅 https://github.com/guzzle/promises#synchronous-wait - 调用
Promise::wait()
“用于同步强制完成承诺”。

参考:https://github.com/guzzle/guzzle/issues/1429#issuecomment-197119452


6
投票

如果您不关心响应,则应执行以下操作:

try {
    $this->guzzle->post('http://myurl.com/doNotWait', ['timeout' => 1]);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
    // do nothing, the timeout exception is intended
}

因此,这里请求将花费 1 秒,代码将继续执行。


0
投票

进行异步调用以创建 Promise,然后调用 then() 方法,无需回调

$client = new GuzzleClient();
$promise = $client->getAsync($url)
$promise->then();

0
投票

既然其他人写道,Guzzle 没有为此提供内置解决方案,这里有一个解决方案:

$url = escapeshellarg("http://myurl.com/doNotWait");
exec("wget -O /dev/null -o /dev/null " . $url . " --background")

它使用 exec (https://www.php.net/manual/de/function.exec.php) 来运行命令行工具

wget
(https://de.wikipedia.org/wiki/Wget) - 它包含在大多数 Linux 发行版中,并且也适用于 Windows 和 OSX)命令。我只在 Linux 上进行了测试,因此可能需要根据您的操作系统调整参数。

让我们把它分成几部分

  • -O /dev/null
    :请求的结果应该发送到null(无处)
  • -o /dev/null
    :日志应发送至 null
  • $url
    :您要调用的网址,例如
    http://myurl.com/doNotWait
  • --background
    :后台运行,无需等待。

对于那些认为“exec”是邪恶的人:如果参数来自用户输入,那么你可能是对的。如果 url 是由您的代码定义的,则不是。


-2
投票

根据要求即发即忘。其中一个解决方案对我有用。

 $client = new \GuzzleHttp\Client(['timeout' => 0.001]);        
 $promise = $client->requestAsync('GET', 'http://dummy.site');

 try {
        $promise->wait();
 } catch (\Exception $ex) {
        ## Handle                       
 }

如果未调用

$promise->wait();
,则不会执行请求。

© www.soinside.com 2019 - 2024. All rights reserved.