isConnected() 返回连接状态的快照而非实时可用性:true仅表示connect()已调用且未触发onError/onClose,不保证TCP通断;异步客户端需在onConnect后才为true;不可用于健康检查,须通过send/recv或心跳机制验证。

swoole_client->isConnected() 返回的是什么状态
isConnected() 只反映应用层连接动作是否完成,不等于连接可用。它返回 true 仅表示:connect() 已调用且未触发 onError 或 onClose,底层 socket 处于“已建立但未关闭”的中间态。
这个状态和 TCP 实际通断无关——网络闪断、对端进程崩溃、防火墙静默丢包后,isConnected() 仍可能返回 true,直到你执行 send() 或 recv() 才暴露问题。
- 同步客户端:调用
connect()成功后立即为true,失败则不进入该状态 - 异步客户端:
connect()立即返回true,但此时isConnected()是false;只有onConnect触发后才变为true - 调用
close()后,isConnected()立即返回false,哪怕底层 TCP 连接尚未真正断开(如 FIN 还在传输中)
为什么不能靠 isConnected() 做连接健康检查
因为它是静态快照,不是实时探测。常见误用场景:
- 在定时器里反复调用
isConnected()判断连接是否存活 → 结果永远是true,直到你主动 send/recv - 用它替代心跳机制 → 客户端掉线后服务端无法感知,
$server->exist($fd)仍返回true - 在
onReceive之前依赖它做权限校验 → 可能漏掉刚连上还没发数据的合法连接
真正可靠的判断必须触发内核交互:send() 返回 false、recv() 返回空或 false、或 getsockopt(SO_ERROR) 检查错误码(需底层支持)。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
服务端 fd 存活判断应该用 exist() 还是 isEstablished()
两者都比 isConnected() 更贴近真实连接状态,但适用场景不同:
-
$server->exist($fd):通用,适用于 TCP/UDP/WebSocket,只要 fd 在连接池里就返回true;但它不区分“刚 accept 进来但握手未完成”的半连接 -
$server->isEstablished($fd):严格,只对已完成三次握手的 TCP 连接或 WebSocket 握手成功的连接返回true;Swoole 4.4+ 中推荐用于 WebSocket 场景 - UDP 不适用
isEstablished(),只能用exist()或发送试探包
注意:exist() 和 isEstablished() 都不解决“连接已建立但链路不通”的问题,必须配合 heartbeat_check_interval + heartbeat_idle_time 启用心跳自动清理。
connect() 调用后 isConnected() 仍是 false 的原因
这是异步客户端的典型表现,本质是事件驱动模型的时序问题:
-
connect()立即返回true,只是把连接请求提交给 Reactor,尚未完成三次握手 - 此时
isConnected()必然为false,因为连接还未真正建立 - 只有 Reactor 收到内核通知(EPOLLIN on connect fd)并触发
onConnect回调后,内部状态才更新,isConnected()才变true - 如果超时(1.9.11+ 版本),会触发
onError,错误码为ETIMEOUT(110),isConnected()保持false
所以异步模式下,所有业务逻辑(如 send)必须放在 onConnect 回调里,而不是 connect() 返回后直接写。

















