server->exist仅检查fd是否在连接表中且状态为active,不验证握手;isestablished则严格要求tcp三次握手或websocket握手完成才返回true。

Server->exist 与 isEstablished 的语义差异
Server->exist 只判断 fd 是否在 Server 的连接表中存在,且状态为 Active —— 它不关心协议类型、不验证握手完成与否,甚至对 UDP 连接也返回 true(只要 fd 没被释放)。而 Server->isEstablished 是严格 TCP/WS 层面的判断:必须已完成三次握手(TCP),或已通过 WebSocket 握手(WS),才返回 true。Swoole 4.4+ 中,exist 对 WebSocket 场景已不推荐用于“是否可用”判断,仅适合快速查表。
什么时候该用 exist,什么时候必须用 isEstablished
以下场景优先选 exist:
- 你只做连接是否存在(比如清理内存缓存、避免空指针)
- 处理的是 UDP 连接(
isEstablished不支持 UDP) - 在
onClose或onWorkerStop回调里做兜底检查(此时连接已断,但 fd 可能尚未从表中移除)
以下场景必须用 isEstablished:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 向 WebSocket 客户端
push前校验连接有效性 - 实现消息广播时排除未完成握手的“半连接”
- 配合
heartbeat_idle_time做主动探测后,需确认连接是否真正就绪
exist 返回 true 却 send 失败?这是正常现象
这是因为 exist 查的是内存连接表快照,而网络层可能已断开但内核尚未通知(如 FIN 包丢失、RST 未达、NAT 超时)。所以:
-
$server->exist($fd)返回 true ≠ 连接可发数据 -
$server->send($fd, $data)返回 false 是最终判决,应以此为准 - 不要省略 send 后的返回值判断,尤其在高并发推送场景下
- 若频繁遇到 exist 为 true 但 send 失败,说明心跳配置不合理,需调低
heartbeat_idle_time或启用open_tcp_keepalive
getClientInfo 配合 exist 使用更可靠
getClientInfo 虽有轻微开销,但它能返回连接的最后活动时间(connect_time 和 last_time),结合 exist 可识别“僵尸连接”:
- 若
exist($fd) === true但last_time距今 > 2×heartbeat_idle_time,大概率已失联 - 若
getClientInfo($fd, 0, true)返回 false 且ignoreError=true,说明连接已关闭但 fd 尚未回收(常见于 dispatch_mode=1/3) - 注意:
getClientInfo在 task 进程中不可用,只能在 worker 进程调用
exist 的结果不具备跨进程一致性**——当使用多 worker 且 dispatch_mode 非 0 时,某个 worker 调用 exist 返回 true,不代表其他 worker 也能立即感知该连接状态变化。真要强一致性判断,得依赖心跳 + 共享内存标记,或改用协程服务器配合 co::sleep 状态轮询。










