onpipemessage仅在swoole_process模式下有效,因swoole_base为单进程无管道;sendmessage走内置管道路由触发该回调,write需手动配对且不触发;task可向worker发消息触发onpipemessage,但反之不行。

onPipeMessage 只在 SWOOLE_PROCESS 模式下有效,其他模式(如 SWOOLE_BASE)根本不会触发 —— 这是绝大多数人踩坑的起点。
为什么 onPipeMessage 在 SWOOLE_BASE 下不工作
因为 SWOOLE_BASE 是单进程模型:没有独立的 Worker 进程,所有回调都在主线程中执行,不存在“进程间”通信的物理基础。管道(pipe)由 Master 进程 fork 出 Worker 时自动创建,而 SWOOLE_BASE 根本不 fork,自然没有管道可读,onPipeMessage 回调永远不会被注册或调用。
- 运行时若误设
worker_num > 1且mode => SWOOLE_BASE,Swoole 不报错但静默忽略onPipeMessage - 可通过
posix_getpid()打印各回调中的 PID 验证:在onWorkerStart里打印,SWOOLE_BASE下所有回调 PID 相同;SWOOLE_PROCESS下每个 Worker PID 不同 - 启动时检查
$server->setting['mode']值是否为SWOOLE_PROCESS(即常量值 2),别只看配置变量名
sendMessage 和 write 的行为差异
$worker->sendMessage() 是封装好的高层接口,它走的是 Swoole 内置的进程间管道机制,会自动触发接收方的 onPipeMessage;而 $process->write() 是底层管道写入,需手动配对 $process->read(),且不触发 onPipeMessage 回调。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
-
$worker->sendMessage('data'):发送目标必须是另一个 Worker 或 Task 进程(通过$server->worker_id或$task_worker_id指定),数据经 Swoole 内部管道路由,接收方自动进onPipeMessage -
$process->write('data'):仅适用于你手动创建的Swoole\Process实例,且必须提前用useQueue或显式pipe建立双向通道,否则写入失败或阻塞 - 注意大小限制:
sendMessage单次上限约 8KB(实际受系统 pipe buffer 影响),超长数据需自行分包或改用消息队列
Task 进程能否触发 onPipeMessage
可以,但方向受限:Task 进程能向 Worker 进程发消息并触发其 onPipeMessage,反之则不行 —— Worker 不能直接向指定 Task 进程发 sendMessage,因为 Task 进程 ID 不稳定、不暴露给 Worker 上下文。
- Worker 向 Task 投递任务用
$server->task($data),结果由onFinish回收,这是单向异步流 - 若需 Task 主动通知 Worker,Task 进程内需保存
$server对象引用(例如通过全局变量或闭包绑定),再调用$server->worker_pid[$target_id]->sendMessage() - 更稳妥的做法是:Task 进程也作为普通 Worker 启动(即不设
task_worker_num),自己管理子进程,用sendMessage互发,避免依赖不稳定 ID
真正容易被忽略的是:onPipeMessage 的执行上下文仍是 Worker 进程,但它**不参与请求生命周期**—— 你不能在里面调用 $server->connection_info() 或操作客户端连接,因为此时没有关联的 $fd。它纯粹是进程信令通道,适合传状态、指令、轻量数据,别把它当 HTTP 请求处理器用。










