websocket客户端需手动实现ping/pong心跳,定时发送并等待响应,间隔须小于中间件超时值(如nginx默认60s→≤45s);重连需指数退避、限制次数并重做初始化;php服务端须禁用超时、设置协议、避免阻塞;心跳必须为应用层json消息且零延迟响应。

WebSocket客户端必须手动实现ping/pong逻辑
textalk/websocket、Ratchet、Workerman 等 Composer 库都不自动发送心跳帧。浏览器原生 WebSocket 也不暴露 sendPing() 方法,服务端如未收到业务层心跳,超时后会主动关闭连接——这不是库的缺陷,而是协议设计使然。
常见错误现象:Connection closed before receiving a handshake response、EOF、刚发一条消息就报 Connection is closed,往往不是连不上,而是连上后没维持住。
- 客户端需定时调用
$ws->ping()(注意部分服务端要求ping数据为特定字符串,如"ping"或空字节) - 不能只依赖服务端单向发 ping:客户端也得主动发,并等待
pong响应,否则无法感知自身网络已断 - 心跳间隔必须小于所有中间件空闲超时值(Nginx
proxy_read_timeout默认 60s → 心跳 ≤45s;AWS ALB 默认 60s → 同样需预留缓冲)
重连不能靠 setTimeout 简单轮询
前端用原生 WebSocket 对象时,onclose 事件只返回 event.code 和 event.reason,而网络闪断、NAT 超时等场景统一返回 1006(abnormal closure),无法区分是服务端主动下线还是链路中断。
真实重连逻辑必须结合多维度判断:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 捕获
WebSocket\ConnectionException或receive()返回空/抛异常,作为断连信号 - 首次重连延迟设为
1000ms,失败后按指数退避增长(2000ms → 4000ms → 8000ms…上限建议60000ms) - 限制最大重试次数(如 10 次),避免无限循环打爆服务端或触发防火墙限流
- 重连成功后,需重新执行认证、订阅、同步状态等初始化动作,不能直接复用旧连接上下文
PHP服务端需禁用脚本超时并接管事件循环
Ratchet 或 Workerman 在 CLI 模式下运行,但默认仍受 PHP 配置约束:max_execution_time 会杀死进程,ignore_user_abort 不启用则终端关闭导致守护进程退出。
关键配置缺一不可:
- 启动脚本开头必须加
set_time_limit(0)和ignore_user_abort(true) - 不能在
onMessage中执行file_get_contents、sleep()等同步阻塞操作,否则整个事件循环卡死 -
Worker::$protocol = 'websocket'必须显式设置,否则客户端用wss://或ws://协议也连不上(只是裸 TCP) - 若使用 Nginx 反代,需确认其
proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade"已正确配置
心跳包格式与检测逻辑要穿透所有中间件
TCP keepalive 是内核级机制,对应用层不可见,且无法穿透代理/NAT 设备。真正起作用的是应用层心跳——它必须是能被所有中间设备识别、转发、不被截断或改写的普通业务消息。
推荐做法:
- 心跳消息用 JSON 格式,如
{"type":"ping","ts":1719112822},服务端响应{"type":"pong","ts":1719112822},便于调试和时间戳校验 - 客户端发送心跳后,启动一个
setTimeout计时器(比如 5s),超时未收pong则标记连接异常,而非等到下次onclose才反应 - 服务端收到
ping后必须立即回pong,不能排队等待;若业务逻辑复杂,可先发pong再异步处理其他消息 - 别把心跳和业务消息混在一个通道里做优先级调度——心跳必须“零延迟”响应,否则保活失效










