Swoole HTTPS keep-alive 响应内容较大时,会出现最后一段数据需要在链接断开时才会触发事件回调的情况
還沒有人認領這個 Issue。
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 35/100
- Issue 類型
- 缺陷
- 描述清晰度
- 基本清楚
- 活躍度
- 停滯
- 技術堆疊
- php
- 領域
- networking
研究方向
使用 issue 中的範例重現 keep-alive 請求,然後檢查 \Workerman\Events\Swoole::callRead() 以及圍繞緩衝回應資料的 Swoole 事件處理。將 keep-alive 與 Connection: close 進行比較,並新增一個回歸測試,證明最後一個小資料區塊會觸發進度和成功,而無需等待連線關閉或逾時。
由索引模型根據 Issue 內容生成。
描述
代码如下:
$connection = $request->connection;
$client = new Client([
'max_conn_per_addr' => 128, // 每个域名最多维持多少并发连接
'keepalive_timeout' => 30, // 连接多长时间不通讯就关闭
'connect_timeout' => 5, // 连接超时时间
'timeout' => 120, // 请求发出后等待响应的超时时间
]);
$client->request('https://app.unpkg.com/[email protected]/files/dist/vue.esm-browser.js', [
'method' => 'GET',
'version' => '1.1',
'headers' => ['Connection' => 'keep-alive'],
'progress' => function($buffer) use ($connection) {
$connection->send(new Chunk(time()." 响应大小: " . strlen($buffer).PHP_EOL));
},
'success' => function($response) use ($connection) {
$connection->send(new Chunk(time()." 响应成功"));
$connection->send(new Chunk('')); // 发送空的的chunk代表response结束
},
'error' => function (\Throwable $exception) use ($connection) {
$connection->send(new Chunk(time()." 响应失败: ".$exception->getMessage()));
$connection->send(new Chunk(''));
},
]);
return new Response(200, ["Transfer-Encoding" => "chunked"], '');
请求的这个 js 文件大小为 535 kB,由于开启了 keepalive,所以服务器会保持链接 60s,此时会出现能正常速度的输出很大一部分的响应大小,然后在最后一点内容的时候会一直 hang 住,直到链接被服务器关闭,才能正常的输出响应成功,或者是读取超时被 ConnectionPool 主动断开,如下所示:
....
1750845988 响应大小: 8192
1750845988 响应大小: 8192
1750845988 响应大小: 8192
1750846107 响应失败: read 104.18.0.22:443 timeout after 120 seconds
但如果将headers中的Connection设置为close,即:
'headers' => ['Connection' => 'close'],
此时再请求就会很正常的完成输出:
...
1750845798 响应大小: 8192
1750845798 响应大小: 8192
1750845798 响应大小: 7295
1750845798 响应成功
环境:
> php -v
PHP 8.2.8 (cli) (built: Jul 10 2023 23:07:42) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.8, Copyright (c) Zend Technologies
with Zend OPcache v8.2.8, Copyright (c), by Zend Technologies
> php --ri swoole
swoole
Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 6.0.2
Built => Jun 25 2025 10:47:55
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
sockets => enabled
openssl => OpenSSL 3.1.8 11 Feb 2025
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
curl-version => 8.12.1
c-ares => 1.19.1
zlib => 1.2.13
brotli => E16777225/D16777225
zstd => 1.5.5
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
mysqlnd => enabled
io_uring => enabled
Directive => Local Value => Master Value
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608
根据代码追踪,可以确认是\Workerman\Events\Swoole::callRead()方法没有被触发,表现就是最后一段响应长度较小,未能出发 Swoole Event 的可读事件,导致这一部分数据一直在 buffer 中,无法被 PHP 代码读取。具体原因受限于我的知识面,无法深入了解了。
- 主要語言
- PHP
- 星號
- 55
- 分支
- 20
- PR 合併指標
- 30 天內沒有已合併 PR
環境準備
這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
workerman-php/http-client 的其他 Issue
-
難度 3/5 1-2 天 新手友好度 52/100
workerman-php/http-client#48 ·
-
TLS 1.3未關閉
難度 4/5 3-5 天 新手友好度 35/100
workerman-php/http-client#32 ·
-
難度 5/5 一週以上 新手友好度 20/100
workerman-php/http-client#23 ·
-
如何忽略SSL 错误未關閉
難度 5/5 一週以上 新手友好度 25/100
workerman-php/http-client#18 · 1 則留言 ·
-
可以升级了未關閉
難度 2/5 1-3 小時 新手友好度 35/100
workerman-php/http-client#17 ·
查看 workerman-php/http-client 的全部 Issue
相似的 Issue
-
難度 1/5 1 小時以內 新手友好度 85/100
-
L: java:gradle L: java:maven L: ruby:bundler T: bug 🐞
難度 2/5 1-3 小時 新手友好度 76/100
dependabot/dependabot-core#16547 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 65/100
glpi-project/glpi#25922 ·
維護者通常 1 天內回覆
-
Bug
難度 2/5 1-3 小時 新手友好度 70/100
Automattic/safe-publish#726 ·
維護者通常 1 天內回覆
-
[Translation][TwigBridge][TwigBundle] Add `HtmlTranslator` and the `tra…可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉Translation TwigBridge
難度 2/5 1-3 小時 新手友好度 68/100
symfony/symfony-docs#23308 ·
維護者通常 3 天內回覆