open_eof_check仅检查包末尾是否匹配eof,性能高但无法识别中间eof;open_eof_split扫描全缓冲区自动切分,cpu开销大;两者混用时后者覆盖前者;更推荐open_length_check,靠包头长度定界,稳定高效。

open_eof_check 只看包末尾,快但不拆中间
它只用 memcmp 比对收到数据的末尾几个字节是否等于 package_eof,比如 "\r\n"。匹配就整包投递给 onReceive,不匹配就继续缓存拼接。
- 性能极高,几乎无 CPU 开销
- 无法识别包中间的
package_eof,所以一次可能收到多个完整包(例如客户端连续发了两条"hello\r\nworld\r\n",服务端收到的就是一整段) - 你必须在业务代码里手动
explode("\r\n", $data)拆分,否则会把多条消息当一条处理 - 适用于协议严格、发送方可控的场景(如自建文本命令行协议),且确保业务数据里绝不会出现
package_eof
open_eof_split 会扫描整个缓冲区找 EOF,慢但自动切分
启用后,Swoole 会从左到右逐字节扫描整块接收数据,只要遇到 package_eof 就立即切一刀,保证每次 onReceive 只拿到一个以 EOF 结尾的完整包。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 无需你在 PHP 层手动
explode,逻辑更干净 - 代价是 CPU 消耗陡增:每秒 1 万次 2MB 包,就要做约 20GB 字符对比
- 即使没设
open_eof_check,open_eof_split也生效 —— 它不依赖前者 - 适合客户端不可控、或不愿/不能改应用层拆包逻辑的项目,但务必压测 CPU 使用率
两者混用时,open_eof_split 实际上覆盖 open_eof_check
如果你同时设置 'open_eof_check' => true 和 'open_eof_split' => true,底层会跳过末尾检测逻辑,直接走全量扫描分包路径。也就是说,open_eof_check 在这种情况下形同虚设。
- 不要以为开了两个就“更保险”——没有叠加效果,只有执行路径切换
-
open_eof_check的唯一价值是“零开销判断”,一旦需要中间切分,它就退场了 - 配置中保留
open_eof_check只会造成语义混淆,建议明确只开其中一个
真正该优先考虑的是 open_length_check
EOF 方案本质是“靠内容猜边界”,脆弱点在于:业务数据万一真含 package_eof,就会提前截断。而 open_length_check 是靠包头声明长度,稳定得多。
- 需要你协议里加 4 字节(或指定长度)包头,用
pack('N', $len)发送 - 对应配置
'open_length_check'=>true, 'package_length_type'=>'N', 'package_length_offset'=>0, 'package_body_offset'=>4 - 既不惧 EOF 冲突,也不扫全文,CPU 和内存都更可控
- 二进制协议、高可靠场景,应该默认选这个,而不是在
open_eof_check和open_eof_split之间纠结
package_max_length 配合问题:不管用哪种 EOF 模式,超长包都会导致内存持续增长,直到触发上限才丢弃并断连。这个值必须根据你的典型包大小谨慎设置,不能留默认。










