关键在于http、tcp和应用三层交叉验证:客户端需声明accept头,服务端须返回chunked或sse响应头并禁用缓存;network面板观察分块持续追加;ss命令查tcp连接状态,配合tcpdump抓包分析保活与重传。

识别大模型长文本输出中 fetch 持续连接的稳定性,关键不在“有没有连接”,而在于“连接是否在该用的时候始终可用”。这需要从 HTTP 层、TCP 层和应用行为三个层面交叉验证,而不是只看状态码或控制台日志。
看 fetch 请求头与响应头是否真正启用流式通道
真正的流式连接必须满足两个基础条件:客户端明确声明接受 SSE 或流式响应,服务端也按规范返回对应头部。
- 客户端 fetch 需设置 headers: { 'Accept': 'text/event-stream' }(SSE)或至少不阻断流式响应(如禁用 compression 可能干扰 chunked transfer)
- 服务端响应必须含:Content-Type: text/event-stream(SSE)或 Content-Type: application/json + Transfer-Encoding: chunked(普通流式)
- 必须有 Connection: keep-alive,且 Cache-Control: no-cache(避免中间代理缓存整段响应)
观察网络面板中 response body 是否分块持续到达
浏览器 DevTools 的 Network 面板是第一手诊断工具。选中该 fetch 请求后,关注 Response 标签页的实时变化:
将小说章节转换为电影分镜剧本。用户上传txt/md/docx文本,AI分析场景、角色、情绪、镜头语言,输出专业分镜脚本。适用于用户提及“分镜”“storyboard”“小说转分镜”“影视改编”“镜头脚本”或需要将小说改编为分镜的场景。
- 如果内容是“一次性刷出”或长时间空白后突然全部出现 → 连接未真正流式,可能是服务端缓冲未关闭(如 PHP 未调用
flush())、反向代理(Nginx)未配置proxy_buffering off) - 如果内容随时间推移逐段追加(可见换行符、data: 字段、JSON 块逐步拼合),且状态栏显示“Transferring data…”持续数十秒以上 → 流式通道已建立,TCP 连接正在被复用
- 若中途出现“Failed”或“Canceled”,但请求已发出数秒 → 很可能触发了 TCP 层保活超时或中间设备(如 NAT、防火墙)静默断连
检查 TCP 连接是否被内核或中间设备悄悄关闭
HTTP 层的 keep-alive 是逻辑概念,底层依赖 TCP 的活跃性。即使响应头写了 Connection: keep-alive,若 TCP 连接本身因空闲被切断,fetch 就会中断。
- Linux 服务端可查当前连接状态:
ss -tnp | grep :your_port,观察是否存在大量ESTAB但无数据收发的连接;若有大量CLOSE_WAIT,说明服务端未及时 close socket - 关键内核参数影响空闲连接寿命:
/proc/sys/net/ipv4/tcp_keepalive_time(默认 7200 秒)、_intvl(默认 75 秒)、_probes(默认 9 次)。若大模型单次生成耗时超过 2 小时,需调小tcp_keepalive_time - 更常见的是中间网络设备(如家用路由器、企业防火墙)设置更激进的 idle timeout(常为 30–300 秒)。此时仅靠 TCP keepalive 不够,必须配合应用层心跳(如 SSE 中定期发送
data: \n\n心跳事件)
用 curl 模拟并捕获底层 TCP 行为
绕过浏览器封装,直接验证 TCP 层稳定性:
- 执行:
curl -N -H "Accept: text/event-stream" http://localhost:8000/chat,-N禁用 buffering,观察是否持续输出 - 同时另开终端运行:
tcpdump -i any port 8000 -w keepalive.pcap,抓包后用 Wireshark 打开,过滤tcp.keepalive,确认保活探测包是否按预期发出且收到 ACK - 若看到大量重传(Retransmission)或连接被 RST 关闭,说明链路存在丢包或策略拦截,需排查网络路径而非应用代码










