codex websocket反复断开需四层排查:先查客户端日志与network中101状态及onclose码(如1006);再验服务端心跳配置(如spring boot设setheartbeatvalue);三查nginx等代理的proxy_read/send_timeout≥300及http/1.1;最后tcpdump抓包定位rst来源。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

排查Codex中WebSocket连接反复断开的问题,需从客户端日志、服务端心跳配置、代理层超时设置和网络中间件四方面逐层验证,跳过任意一层都可能掩盖真实原因。
检查客户端控制台错误与重连行为
打开浏览器开发者工具 → 切换到 Console 标签页 → 刷新页面并观察 WebSocket 相关报错(如 “WebSocket is closed before the connection is established” 或 “Failed to execute ‘send’ on ‘WebSocket’: Still in CONNECTING state”)。
在 Network 标签页中筛选 ws 或 websocket,点击对应连接,查看 Headers 中的 Status 是否为 101,Response 为空或含 “connection: close” 字样,说明握手失败或服务端主动拒绝。
若发现频繁触发 onclose 回调且 event.code 不是 1000,记录具体 code 和 reason —— 【code 1006 表示异常关闭且无明确原因,大概率是底层 TCP 连接被中间设备强制中断】。
验证服务端心跳保活配置
确认 Codex 后端使用的 WebSocket 框架(如 Spring Boot 的 WebSocketConfigurer 或 Netty 实现),检查是否启用 ping/pong 帧自动响应。
方法一(Spring Boot):在 WebSocketConfig 中确认已调用 setHeartbeatValue(new Duration(10, TimeUnit.SECONDS)),否则默认不发心跳,Nginx 等代理会在 60 秒后切断空闲连接。
方法二(自定义 Netty ChannelHandler):检查是否在 channelRead 中拦截了 PingWebSocketFrame 并正确写出 PongWebSocketFrame —— 【漏处理 Ping 帧会导致代理判定连接失活而断开】。
审查反向代理与负载均衡器超时设置
第一步:登录 Nginx 配置文件所在服务器,执行 nginx -t 确认语法正确后,打开 nginx.conf 或 site-enabled 下对应配置。
通过本地 Codex 或 OpenClaw OAuth 凭证直接调用 ChatGPT/Codex Responses 的 image_generation 工具来生成或编辑光栅图像,然后保存
第二步:定位到 upstream 或 location /ws { ... } 块,确认存在以下三行且数值合理:
proxy_read_timeout 300;
proxy_send_timeout 300;
proxy_set_header Upgrade $http_upgrade;
第三步:检查 proxy_http_version 是否为 1.1 —— 若仍是 1.0,Upgrade 头会被忽略,WebSocket 握手直接降级为 HTTP 短连接。
若使用 AWS ALB,需进入监听器规则 → 编辑默认操作 → 将空闲超时(Idle timeout)设为 ≥300 秒;GCP Load Balancer 则需修改 Backend Service 的 connection-draining-timeout 和 timeout。
抓包确认 TCP 层是否被主动 RST
在 Codex 客户端宿主机执行 sudo tcpdump -i any -w ws_debug.pcap port 80 or port 443,复现一次断开过程后 Ctrl+C 停止。
用 Wireshark 打开 pcap 文件,过滤 websocket && tcp.flags.reset == 1,观察 RST 包来源 IP:若是服务端 IP 发出,说明服务端进程崩溃或主动 close;若是防火墙/NAT 设备 IP(如 192.168.1.1 或运营商网关地址),则问题出在中间网络策略。
这一步操作起来很简单,直接把文件拖进去就行。但注意:必须在客户端本机抓包,服务端抓到的包可能已被代理改写源地址,无法定位真实中断点。










