问题背景:
做了个api接口,使用到第三方的api,为避免进程阻塞,使用了异步请求第三方api,但是第三方的请求结果无法返回给客户端,这个要怎么解决?
代码如下:
use Workerman\Http\Client;
use support\Request;
class TestController
{
public function test(Request $r)
{
$options = [
'max_conn_per_addr' => 128, // 每个地址最多维持多少并发连接
'keepalive_timeout' => 15, // 连接多长时间不通讯就关闭
'connect_timeout' => 30, // 连接超时时间
'timeout' => 30, // 等待响应的超时时间
];
$http = new Client($options);
$url = $r->input('url');
$http->get($url, function($response){
$body = $response->getBody();
return response($body); // <------ 想要把这个结果发给客户端,请问如何实现呢?
}, function($exception){
echo $exception;
});
return 'sync ok'; // <----客户端只能收到这个结果
}
}
实现了一个不太好的方案如下,但是该方案会有一个问题,不会关闭连接。请问官方有没有计划支持类似的场景
新建文件
support\HoldConnetion.php, 代码如下:
修改TestController的代码如下:
异步请请求建议用自定义进程去做。
process/api.php
config/process.php
访问
http://127.0.0.1:8686/test/test
nginx做个代理,将需要异步的接口比如
/test/test
转发到端口8686即可感谢回复,使用自定义进程去做会存在以下问题:
1.不可 复用路由 和 中间件 等配置(?)
2.由于业务原因,几乎所有接口都会调用第三方 (第三方可能是公司内部其它服务) 的API, 改动起来较大
从webman代码看,从框架层面支持该功能似乎改动不大,比如在 webman\App:send 方法里加个判断response类型
即可。
大佬是否考虑从框架层面增加支持,毕竟可以大大增加抗并发能力,场景也比较通用。
这个暂时不支持。后面workerman v5出来,可以做到框架和业务代码不用改动,支持异步调用url,以同步的方式返回结果。v5发布时间还没确定,你可以先用你现在的方案开发
现在可以用php8.1 workerman V5 协程了,贼屌
v5发布了?
v5.0.0-beta.5 这个版本没啥问题,我测试用了,协程很好用,windows 单进程 请求第三方不会阻塞,无敌
分享下 哈哈
很简单 https://www.workerman.net/doc/workerman/components/workerman-http-client.html 协程用法,webman中写法也是一样的
$http = new Client($options);
$url = 'http://***';
$response = $http->request($url, [
'method' => 'POST',
'version' => '1.1',
'headers' => $ypHeader,
'data' => json_encode($data),
]);
$r = $response->getBody()->getContents();
我压测,这个真不阻塞,能同时接受1000请求
这个不太符合我的场景, 我的场景是 A->我->C , 我需要异步请求C,然后把结果再响应给A。
你这个只能做到A->我, 我异步->C, 我异步->D,请求C、D时是没有阻塞的,但是结果无法响应给A了。
搜索了一番发现在同步里调用异步实现我这种场景是做不到的,只能反过来,即异步里调用同步,英语好的可以看下
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
我不太明白你的意思,但是我看这个协程是可以符合你的需求的啊。 你的需求是不是搭建web服务端提供api给A方调用,然后你的服务端程序调用C方的api,最终将C方的返回结果返回给A方? 如果是这样的话,在你的程序里使用异步客户端的方式调用C接口。这样你的服务端程序进程不会阻塞啊,A方可以进来更多的请求。可以试一下
这个是walkor这几天发的v5,一起学习下
https://www.workerman.net/q/10564
下面是我提问的,问完我就去测试了,redis 协程没成功,qps基本没差别,估计是redis足够快的原因,请求外网第三方协程方式,很好用,不阻塞,普通方式请求第三方开一个进程,qps基本几个,协程方式一个进程居然能跑好几百
我还没实验,不过异步协程webman中不是只有一个HTTP客户端:workerman/http-client吗,怎么还有异步redis?
有可以使用 异步redis