Swoole协程HTTP客户端必须在协程中运行,否则connect()立即返回false;timeout仅在connect()和execute()参数中生效,读写超时需set(['timeout'=>x]);HTTP/2需显式启用并开启SSL;Cookie隔离靠实例独立,禁止复用client。

new Swoole\Coroutine\Http\Client() 为什么连不上?
协程客户端必须在协程环境中运行,直接 new 出来但没进协程,connect() 会立刻返回 false,且不报错——这是最常卡住的地方。
- 确认当前是否在协程内:用
Swoole\Coroutine::getuid()检查,返回false或null就说明不在协程中 - 别在主进程或同步回调里初始化它,比如
onReceive(非协程模式)或__construct中直接 new - 正确做法是:用
Swoole\Coroutine\run()包裹,或在go(function () { ... })里创建
timeout 参数传哪里才生效?
timeout 不是构造函数参数,也不是 set() 的通用配置项,它只在 connect() 和 execute() 这两个调用点上起作用,而且语义不同。
-
connect('127.0.0.1', 80, 3.0)的第三个参数是连接超时(单位秒),不是读写超时 -
execute('/api', 'POST', $data)的第三个参数是整个请求生命周期上限(含 DNS、connect、send、recv),但仅限 HTTP/1.1;HTTP/2 下该参数被忽略 - 真正控制读写超时要用
set(['timeout' => 5.0]),但它只影响后续的recv()行为,对connect()无效
HTTP/2 客户端怎么开?
不是加个 ssl 就自动走 HTTP/2,Swoole 要求明确启用,并且服务端必须支持 ALPN。
- 构造时必须传
true第四个参数:new Swoole\Coroutine\Http\Client('httpbin.org', 443, true, true),最后这个true表示启用 HTTP/2 - 必须开启 SSL(第三个参数为
true),HTTP/2 over TCP 不被支持 - 如果
upgrade()失败或$client->getProtocol() === 1,说明协商失败,常见原因是服务端没配 ALPN 或用了自签名证书没加set(['ssl_cert_file' => ...])
并发请求时 Cookie 怎么隔离?
每个 Swoole\Coroutine\Http\Client 实例自带独立 Cookie 上下文,但开发者常误以为“全局 Cookie 管理”存在,结果多个请求互相污染。
- 不需要手动调用
setCookie()来传递;只要复用同一个实例,它的setCookie()和自动解析就自然生效 - 千万别在多个协程里共享一个 client 实例——它不是线程安全的,更不是协程安全的;每次
go都该 new 一个新实例 - 如需跨请求带 Cookie,用
$client->cookies读取后手动塞到下一个 client 的setCookie(),但注意有效期和 domain 匹配逻辑得自己判
HTTP/2 的 stream 复用、协程调度时机、SSL 握手缓存这些底层行为,会让超时和重试逻辑比看起来复杂得多。别依赖默认值,每个 timeout 都得按实际链路环节单独设。










