使用 guzzle 发送异步请求而不等待响应
Send asynchronous request without waiting the response using guzzle
我有以下两个功能
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.
要将其从未答复列表中删除:
Guzzle 不支持 "fire and forget" 没有深度破解的异步请求。
异步方法是 Client::requestAsync()
的抽象,returns 是一个承诺。请参见 https://github.com/guzzle/promises#synchronous-wait - 调用 Promise::wait()
"is used to synchronously force a promise to complete"。
参考:https://github.com/guzzle/guzzle/issues/1429#issuecomment-197119452
由于其他人写道,Guzzle 没有为此提供内置解决方案,这里有一个解决方案作为一个内衬:
$url = "http://myurl.com/doNotWait";
exec("wget -O /dev/null -o /dev/null " . $url . " --background")
它使用 exec(https://www.php.net/manual/de/function.exec.php) to run the commandline tool wget
(https://de.wikipedia.org/wiki/Wget - 它包含在大多数 linux 发行版中,也适用于 Windows 和 OSX)命令。我仅在 linux 上对其进行了测试,因此可能必须针对您的 OS.
调整参数
让我们把它分成几个部分
-O /dev/null
:请求的结果应该发送到null(无处)
-o /dev/null
: 日志应该发送到 null
$url
:你要调用的url,例如http://myurl.com/doNotWait
--background
: 运行在后台,请勿等待。
进行异步调用以创建 promise,然后调用没有回调的 then() 方法
$client = new GuzzleClient();
$promise = $client->getAsync($url)
$promise->then();
如果您不关心响应,应该执行以下操作:
try {
$this->guzzle->post('http://myurl.com/doNotWait', ['timeout' => 1]);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
// do nothing, the timeout exception is intended
}
因此,此处请求将花费 1 秒,代码将继续执行。
我有以下两个功能
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.
要将其从未答复列表中删除:
Guzzle 不支持 "fire and forget" 没有深度破解的异步请求。
异步方法是 Client::requestAsync()
的抽象,returns 是一个承诺。请参见 https://github.com/guzzle/promises#synchronous-wait - 调用 Promise::wait()
"is used to synchronously force a promise to complete"。
参考:https://github.com/guzzle/guzzle/issues/1429#issuecomment-197119452
由于其他人写道,Guzzle 没有为此提供内置解决方案,这里有一个解决方案作为一个内衬:
$url = "http://myurl.com/doNotWait";
exec("wget -O /dev/null -o /dev/null " . $url . " --background")
它使用 exec(https://www.php.net/manual/de/function.exec.php) to run the commandline tool wget
(https://de.wikipedia.org/wiki/Wget - 它包含在大多数 linux 发行版中,也适用于 Windows 和 OSX)命令。我仅在 linux 上对其进行了测试,因此可能必须针对您的 OS.
让我们把它分成几个部分
-O /dev/null
:请求的结果应该发送到null(无处)-o /dev/null
: 日志应该发送到 null$url
:你要调用的url,例如http://myurl.com/doNotWait
--background
: 运行在后台,请勿等待。
进行异步调用以创建 promise,然后调用没有回调的 then() 方法
$client = new GuzzleClient();
$promise = $client->getAsync($url)
$promise->then();
如果您不关心响应,应该执行以下操作:
try {
$this->guzzle->post('http://myurl.com/doNotWait', ['timeout' => 1]);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
// do nothing, the timeout exception is intended
}
因此,此处请求将花费 1 秒,代码将继续执行。