1.关键环境
- laravel版本:5.4
- guzzlehttp/guzzle:6.3.3
2.额外知识
- 使用 Guzzle 中间件进行请求重试的demo地址:https://learnku.com/articles/31855
- Guzzle源码学习地址:https://segmentfault.com/p/1210000011674167/read
有兴趣的可以学习它的源码
3.相关代码
(1)修改GuzzleHttp\Psr7\Uri的源码,新增一个修改当前对象的query属性的方法
/**
* change this object's query
*
* @param $query
* @return $this
*/
public function changeQuery($query)
{
$query = $this->filterQueryAndFragment($query);
if ($this->query === $query) {
return $this;
}
$this->query = $query;
return $this;
}
(2)使用方式,在重试决策者里使用
/**
* retryDecider
*
* @return \Closure
*/
protected static function retryDecider()
{
return function (
$retries,
Request $request,
Response $response = null,
RequestException $exception = null
) {
if ($retries >= 3) {
// to do something
return true;
}
if ($exception instanceof ConnectException) {
// to do something
return true;
}
if ($response) {
if ($response->getStatusCode() >= 500) {
// to do something
return true;
}
$content = $response->getBody()->getContents();
$res = json_decode($content, true);
// request failed
if ($res['status'] == false) {
// token error 假设token的相关错误码为 20001、20002
if (in_array($res['errno'], [20001, 20002])) {
//reflush token
$token = '刷新token后的值';
//change query
$request->getUri()->changeQuery("token={$token}");
return true;
}
}
}
return false;
};
}
$request->getUri()返回的是GuzzleHttp\Psr7\Uri的对象。对象变量只是保存一个标识符来访问真正的对象内容。当对象作为参数传递,作为结果返回,或者赋值给另外一个变量,只是他们都保存着同一个标识符的拷贝,这个标识符指向同一个对象的真正内容。