-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PSR Request的exec()方法是否应该实现在saber上比较妥当? #35
Comments
另外 现有的PSR实现其实不符合PSR标准。按照PSR message的标准,所有的PSR的Request都应该是只读的,也就是说 |
@ihipop 你说的实现在Saber上是正确的主意, 我会继续构思重构这一部分 Saber2.0已经在我的计划中了, 如果你有什么想法建议可以继续讨论 |
我的意思也不是让你去做一个guzzle handler,因为确实很多强Swoole相关的东西。
|
二:客户端重用长连接 现在的文档里面说客户端会自动复用长连接,看了代码确实对同目的地同端口的服务器都做了连接池,但是,实测如果走PSR方式,客户端并不复用长连接,连接不停的出现SYN_SENT、ESTABLISHED、LocalPort的状态切换。 动图: |
@inipop |
@twose 你是对的,以为和Guzzle一样 单一实例会自动复用长连接,看了你代码你是和池绑定到了一起,只有开启池的时候才会使用长连接,否则就算重复请求同一个服务器也不会使用长连接。 |
设计上池是全局共享的, 开启 |
@twose 但是文档里面 Keepalive默认也是true,并没有说明 use pool以后keepalive才会生效 |
生成的PSR对象打印 具体的问题代码如下: Lines 504 to 516 in 5cd1134
这这判断如果本request不和某个client关联,就检查连接池设置,如果没开启池,就始终创建新连接。这样就算默认的Request设置了keepalive是true,也会导致因为客户端每次都是新建的,不使用长连接。这与文档描述行为:长连接默认开启不符。 |
@ihipop 不开启池 你也没保存客户端对象 对象就析构了 连接自然就断开了 |
也就是说在目前的设计下,因为客户端和$request绑定,PSR风格下¥request因为总是新建的,如果不开启池, 所以客户端只请求一次就析构了。 |
@ihipop request上只是相当于保存了client的指针而已, 你需要 |
Lines 17 to 25 in 5cd1134
SaberGM的psr方法默认就会创建一个默认saber客户端,多次调用返回的是同一个,你保存在静态属性里面了。 Line 515 in 5cd1134
他才负责具体的发送和长连接保持。 |
嗯 你是对的 这个应该考虑改动设计了 |
TL;DR 整理一下结论二:
|
实测,即使不使用PSR模式,只要不开启池,那么长连接都是不生效的,具体原因就是之前分析的那些,Request你每次都是新建的。请问,在不重构设计之前,接受PR文档修正增加配置描述还是PR代码补丁修复? $testSaber = function () {
$saber = \Swlib\Saber::create([
'base_uri' => 'http://127.0.0.1:8081',
// 'use_pool' => true,
'headers' => [
'Accept-Language' => 'en,zh-CN;q=0.9,zh;q=0.8',
'Content-Type' => \Swlib\Http\ContentType::JSON,
'DNT' => '1',
'User-Agent' => null,
],
]);
while (true) {
if (!($saber->get('/anything'))) {
echo 'FAILED' . PHP_EOL;
};
}
};
for ($i = 1; $i <= 2; $i++) {
go(function () use ($testSaber) {
$testSaber();
});
} |
可以暂时修改文档描述, 代码补丁会在下个版本 |
PSR的RequestInterface没有规定实现exec方法,所以我设计组装一个http客户端无关的request的时候,我肯定不能绑定和客户端强相关的exec方法到Request上,因为每个客户端的异常类型、处理逻辑都不相同。
我设计一个composer组件,在组装请求部分,返回了个psr对象,本意是guzzle或者saber等支持PSR标准的HTTP客户端都可以按psr标准把这个对象代表的请求发送出去,现在Guzzle可以做到(
$guzzleClient->send($PSRrequest)
)而saber因为把PSR相关的处理逻辑绑定到他自定义的Request上,导致这样的设计没法实施。The text was updated successfully, but these errors were encountered: